[SCSI] Deprecate SCSI_PROT_*_CONVERT operations
[linux-2.6/next.git] / arch / powerpc / xmon / xmon.c
blobc6f0a71b405ee97bce3f7753147cfe4adc1f3fda
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 inline int unrecoverable_excp(struct pt_regs *regs)
340 #ifdef CONFIG_4xx
341 /* We have no MSR_RI bit on 4xx, so we simply return false */
342 return 0;
343 #else
344 return ((regs->msr & MSR_RI) == 0);
345 #endif
348 static int xmon_core(struct pt_regs *regs, int fromipi)
350 int cmd = 0;
351 struct bpt *bp;
352 long recurse_jmp[JMP_BUF_LEN];
353 unsigned long offset;
354 unsigned long flags;
355 #ifdef CONFIG_SMP
356 int cpu;
357 int secondary;
358 unsigned long timeout;
359 #endif
361 local_irq_save(flags);
363 bp = in_breakpoint_table(regs->nip, &offset);
364 if (bp != NULL) {
365 regs->nip = bp->address + offset;
366 atomic_dec(&bp->ref_count);
369 remove_cpu_bpts();
371 #ifdef CONFIG_SMP
372 cpu = smp_processor_id();
373 if (cpu_isset(cpu, cpus_in_xmon)) {
374 get_output_lock();
375 excprint(regs);
376 printf("cpu 0x%x: Exception %lx %s in xmon, "
377 "returning to main loop\n",
378 cpu, regs->trap, getvecname(TRAP(regs)));
379 release_output_lock();
380 longjmp(xmon_fault_jmp[cpu], 1);
383 if (setjmp(recurse_jmp) != 0) {
384 if (!in_xmon || !xmon_gate) {
385 get_output_lock();
386 printf("xmon: WARNING: bad recursive fault "
387 "on cpu 0x%x\n", cpu);
388 release_output_lock();
389 goto waiting;
391 secondary = !(xmon_taken && cpu == xmon_owner);
392 goto cmdloop;
395 xmon_fault_jmp[cpu] = recurse_jmp;
396 cpu_set(cpu, cpus_in_xmon);
398 bp = NULL;
399 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
400 bp = at_breakpoint(regs->nip);
401 if (bp || unrecoverable_excp(regs))
402 fromipi = 0;
404 if (!fromipi) {
405 get_output_lock();
406 excprint(regs);
407 if (bp) {
408 printf("cpu 0x%x stopped at breakpoint 0x%x (",
409 cpu, BP_NUM(bp));
410 xmon_print_symbol(regs->nip, " ", ")\n");
412 if (unrecoverable_excp(regs))
413 printf("WARNING: exception is not recoverable, "
414 "can't continue\n");
415 release_output_lock();
418 waiting:
419 secondary = 1;
420 while (secondary && !xmon_gate) {
421 if (in_xmon == 0) {
422 if (fromipi)
423 goto leave;
424 secondary = test_and_set_bit(0, &in_xmon);
426 barrier();
429 if (!secondary && !xmon_gate) {
430 /* we are the first cpu to come in */
431 /* interrupt other cpu(s) */
432 int ncpus = num_online_cpus();
434 xmon_owner = cpu;
435 mb();
436 if (ncpus > 1) {
437 smp_send_debugger_break(MSG_ALL_BUT_SELF);
438 /* wait for other cpus to come in */
439 for (timeout = 100000000; timeout != 0; --timeout) {
440 if (cpus_weight(cpus_in_xmon) >= ncpus)
441 break;
442 barrier();
445 remove_bpts();
446 disable_surveillance();
447 /* for breakpoint or single step, print the current instr. */
448 if (bp || TRAP(regs) == 0xd00)
449 ppc_inst_dump(regs->nip, 1, 0);
450 printf("enter ? for help\n");
451 mb();
452 xmon_gate = 1;
453 barrier();
456 cmdloop:
457 while (in_xmon) {
458 if (secondary) {
459 if (cpu == xmon_owner) {
460 if (!test_and_set_bit(0, &xmon_taken)) {
461 secondary = 0;
462 continue;
464 /* missed it */
465 while (cpu == xmon_owner)
466 barrier();
468 barrier();
469 } else {
470 cmd = cmds(regs);
471 if (cmd != 0) {
472 /* exiting xmon */
473 insert_bpts();
474 xmon_gate = 0;
475 wmb();
476 in_xmon = 0;
477 break;
479 /* have switched to some other cpu */
480 secondary = 1;
483 leave:
484 cpu_clear(cpu, cpus_in_xmon);
485 xmon_fault_jmp[cpu] = NULL;
486 #else
487 /* UP is simple... */
488 if (in_xmon) {
489 printf("Exception %lx %s in xmon, returning to main loop\n",
490 regs->trap, getvecname(TRAP(regs)));
491 longjmp(xmon_fault_jmp[0], 1);
493 if (setjmp(recurse_jmp) == 0) {
494 xmon_fault_jmp[0] = recurse_jmp;
495 in_xmon = 1;
497 excprint(regs);
498 bp = at_breakpoint(regs->nip);
499 if (bp) {
500 printf("Stopped at breakpoint %x (", BP_NUM(bp));
501 xmon_print_symbol(regs->nip, " ", ")\n");
503 if (unrecoverable_excp(regs))
504 printf("WARNING: exception is not recoverable, "
505 "can't continue\n");
506 remove_bpts();
507 disable_surveillance();
508 /* for breakpoint or single step, print the current instr. */
509 if (bp || TRAP(regs) == 0xd00)
510 ppc_inst_dump(regs->nip, 1, 0);
511 printf("enter ? for help\n");
514 cmd = cmds(regs);
516 insert_bpts();
517 in_xmon = 0;
518 #endif
520 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
521 bp = at_breakpoint(regs->nip);
522 if (bp != NULL) {
523 int stepped = emulate_step(regs, bp->instr[0]);
524 if (stepped == 0) {
525 regs->nip = (unsigned long) &bp->instr[0];
526 atomic_inc(&bp->ref_count);
527 } else if (stepped < 0) {
528 printf("Couldn't single-step %s instruction\n",
529 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
534 insert_cpu_bpts();
536 local_irq_restore(flags);
538 return cmd != 'X' && cmd != EOF;
541 int xmon(struct pt_regs *excp)
543 struct pt_regs regs;
545 if (excp == NULL) {
546 ppc_save_regs(&regs);
547 excp = &regs;
550 return xmon_core(excp, 0);
552 EXPORT_SYMBOL(xmon);
554 irqreturn_t xmon_irq(int irq, void *d)
556 unsigned long flags;
557 local_irq_save(flags);
558 printf("Keyboard interrupt\n");
559 xmon(get_irq_regs());
560 local_irq_restore(flags);
561 return IRQ_HANDLED;
564 static int xmon_bpt(struct pt_regs *regs)
566 struct bpt *bp;
567 unsigned long offset;
569 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
570 return 0;
572 /* Are we at the trap at bp->instr[1] for some bp? */
573 bp = in_breakpoint_table(regs->nip, &offset);
574 if (bp != NULL && offset == 4) {
575 regs->nip = bp->address + 4;
576 atomic_dec(&bp->ref_count);
577 return 1;
580 /* Are we at a breakpoint? */
581 bp = at_breakpoint(regs->nip);
582 if (!bp)
583 return 0;
585 xmon_core(regs, 0);
587 return 1;
590 static int xmon_sstep(struct pt_regs *regs)
592 if (user_mode(regs))
593 return 0;
594 xmon_core(regs, 0);
595 return 1;
598 static int xmon_dabr_match(struct pt_regs *regs)
600 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
601 return 0;
602 if (dabr.enabled == 0)
603 return 0;
604 xmon_core(regs, 0);
605 return 1;
608 static int xmon_iabr_match(struct pt_regs *regs)
610 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
611 return 0;
612 if (iabr == NULL)
613 return 0;
614 xmon_core(regs, 0);
615 return 1;
618 static int xmon_ipi(struct pt_regs *regs)
620 #ifdef CONFIG_SMP
621 if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
622 xmon_core(regs, 1);
623 #endif
624 return 0;
627 static int xmon_fault_handler(struct pt_regs *regs)
629 struct bpt *bp;
630 unsigned long offset;
632 if (in_xmon && catch_memory_errors)
633 handle_fault(regs); /* doesn't return */
635 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
636 bp = in_breakpoint_table(regs->nip, &offset);
637 if (bp != NULL) {
638 regs->nip = bp->address + offset;
639 atomic_dec(&bp->ref_count);
643 return 0;
646 static struct bpt *at_breakpoint(unsigned long pc)
648 int i;
649 struct bpt *bp;
651 bp = bpts;
652 for (i = 0; i < NBPTS; ++i, ++bp)
653 if (bp->enabled && pc == bp->address)
654 return bp;
655 return NULL;
658 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
660 unsigned long off;
662 off = nip - (unsigned long) bpts;
663 if (off >= sizeof(bpts))
664 return NULL;
665 off %= sizeof(struct bpt);
666 if (off != offsetof(struct bpt, instr[0])
667 && off != offsetof(struct bpt, instr[1]))
668 return NULL;
669 *offp = off - offsetof(struct bpt, instr[0]);
670 return (struct bpt *) (nip - off);
673 static struct bpt *new_breakpoint(unsigned long a)
675 struct bpt *bp;
677 a &= ~3UL;
678 bp = at_breakpoint(a);
679 if (bp)
680 return bp;
682 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
683 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
684 bp->address = a;
685 bp->instr[1] = bpinstr;
686 store_inst(&bp->instr[1]);
687 return bp;
691 printf("Sorry, no free breakpoints. Please clear one first.\n");
692 return NULL;
695 static void insert_bpts(void)
697 int i;
698 struct bpt *bp;
700 bp = bpts;
701 for (i = 0; i < NBPTS; ++i, ++bp) {
702 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
703 continue;
704 if (mread(bp->address, &bp->instr[0], 4) != 4) {
705 printf("Couldn't read instruction at %lx, "
706 "disabling breakpoint there\n", bp->address);
707 bp->enabled = 0;
708 continue;
710 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
711 printf("Breakpoint at %lx is on an mtmsrd or rfid "
712 "instruction, disabling it\n", bp->address);
713 bp->enabled = 0;
714 continue;
716 store_inst(&bp->instr[0]);
717 if (bp->enabled & BP_IABR)
718 continue;
719 if (mwrite(bp->address, &bpinstr, 4) != 4) {
720 printf("Couldn't write instruction at %lx, "
721 "disabling breakpoint there\n", bp->address);
722 bp->enabled &= ~BP_TRAP;
723 continue;
725 store_inst((void *)bp->address);
729 static void insert_cpu_bpts(void)
731 if (dabr.enabled)
732 set_dabr(dabr.address | (dabr.enabled & 7));
733 if (iabr && cpu_has_feature(CPU_FTR_IABR))
734 mtspr(SPRN_IABR, iabr->address
735 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
738 static void remove_bpts(void)
740 int i;
741 struct bpt *bp;
742 unsigned instr;
744 bp = bpts;
745 for (i = 0; i < NBPTS; ++i, ++bp) {
746 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
747 continue;
748 if (mread(bp->address, &instr, 4) == 4
749 && instr == bpinstr
750 && mwrite(bp->address, &bp->instr, 4) != 4)
751 printf("Couldn't remove breakpoint at %lx\n",
752 bp->address);
753 else
754 store_inst((void *)bp->address);
758 static void remove_cpu_bpts(void)
760 set_dabr(0);
761 if (cpu_has_feature(CPU_FTR_IABR))
762 mtspr(SPRN_IABR, 0);
765 /* Command interpreting routine */
766 static char *last_cmd;
768 static int
769 cmds(struct pt_regs *excp)
771 int cmd = 0;
773 last_cmd = NULL;
774 xmon_regs = excp;
776 if (!xmon_no_auto_backtrace) {
777 xmon_no_auto_backtrace = 1;
778 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
781 for(;;) {
782 #ifdef CONFIG_SMP
783 printf("%x:", smp_processor_id());
784 #endif /* CONFIG_SMP */
785 printf("mon> ");
786 flush_input();
787 termch = 0;
788 cmd = skipbl();
789 if( cmd == '\n' ) {
790 if (last_cmd == NULL)
791 continue;
792 take_input(last_cmd);
793 last_cmd = NULL;
794 cmd = inchar();
796 switch (cmd) {
797 case 'm':
798 cmd = inchar();
799 switch (cmd) {
800 case 'm':
801 case 's':
802 case 'd':
803 memops(cmd);
804 break;
805 case 'l':
806 memlocate();
807 break;
808 case 'z':
809 memzcan();
810 break;
811 case 'i':
812 show_mem();
813 break;
814 default:
815 termch = cmd;
816 memex();
818 break;
819 case 'd':
820 dump();
821 break;
822 case 'l':
823 symbol_lookup();
824 break;
825 case 'r':
826 prregs(excp); /* print regs */
827 break;
828 case 'e':
829 excprint(excp);
830 break;
831 case 'S':
832 super_regs();
833 break;
834 case 't':
835 backtrace(excp);
836 break;
837 case 'f':
838 cacheflush();
839 break;
840 case 's':
841 if (do_spu_cmd() == 0)
842 break;
843 if (do_step(excp))
844 return cmd;
845 break;
846 case 'x':
847 case 'X':
848 return cmd;
849 case EOF:
850 printf(" <no input ...>\n");
851 mdelay(2000);
852 return cmd;
853 case '?':
854 xmon_puts(help_string);
855 break;
856 case 'b':
857 bpt_cmds();
858 break;
859 case 'C':
860 csum();
861 break;
862 case 'c':
863 if (cpu_cmd())
864 return 0;
865 break;
866 case 'z':
867 bootcmds();
868 break;
869 case 'p':
870 proccall();
871 break;
872 #ifdef CONFIG_PPC_STD_MMU
873 case 'u':
874 dump_segments();
875 break;
876 #endif
877 #ifdef CONFIG_4xx
878 case 'u':
879 dump_tlb_44x();
880 break;
881 #endif
882 default:
883 printf("Unrecognized command: ");
884 do {
885 if (' ' < cmd && cmd <= '~')
886 putchar(cmd);
887 else
888 printf("\\x%x", cmd);
889 cmd = inchar();
890 } while (cmd != '\n');
891 printf(" (type ? for help)\n");
892 break;
898 * Step a single instruction.
899 * Some instructions we emulate, others we execute with MSR_SE set.
901 static int do_step(struct pt_regs *regs)
903 unsigned int instr;
904 int stepped;
906 /* check we are in 64-bit kernel mode, translation enabled */
907 if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
908 if (mread(regs->nip, &instr, 4) == 4) {
909 stepped = emulate_step(regs, instr);
910 if (stepped < 0) {
911 printf("Couldn't single-step %s instruction\n",
912 (IS_RFID(instr)? "rfid": "mtmsrd"));
913 return 0;
915 if (stepped > 0) {
916 regs->trap = 0xd00 | (regs->trap & 1);
917 printf("stepped to ");
918 xmon_print_symbol(regs->nip, " ", "\n");
919 ppc_inst_dump(regs->nip, 1, 0);
920 return 0;
924 regs->msr |= MSR_SE;
925 return 1;
928 static void bootcmds(void)
930 int cmd;
932 cmd = inchar();
933 if (cmd == 'r')
934 ppc_md.restart(NULL);
935 else if (cmd == 'h')
936 ppc_md.halt();
937 else if (cmd == 'p')
938 ppc_md.power_off();
941 static int cpu_cmd(void)
943 #ifdef CONFIG_SMP
944 unsigned long cpu;
945 int timeout;
946 int count;
948 if (!scanhex(&cpu)) {
949 /* print cpus waiting or in xmon */
950 printf("cpus stopped:");
951 count = 0;
952 for (cpu = 0; cpu < NR_CPUS; ++cpu) {
953 if (cpu_isset(cpu, cpus_in_xmon)) {
954 if (count == 0)
955 printf(" %x", cpu);
956 ++count;
957 } else {
958 if (count > 1)
959 printf("-%x", cpu - 1);
960 count = 0;
963 if (count > 1)
964 printf("-%x", NR_CPUS - 1);
965 printf("\n");
966 return 0;
968 /* try to switch to cpu specified */
969 if (!cpu_isset(cpu, cpus_in_xmon)) {
970 printf("cpu 0x%x isn't in xmon\n", cpu);
971 return 0;
973 xmon_taken = 0;
974 mb();
975 xmon_owner = cpu;
976 timeout = 10000000;
977 while (!xmon_taken) {
978 if (--timeout == 0) {
979 if (test_and_set_bit(0, &xmon_taken))
980 break;
981 /* take control back */
982 mb();
983 xmon_owner = smp_processor_id();
984 printf("cpu %u didn't take control\n", cpu);
985 return 0;
987 barrier();
989 return 1;
990 #else
991 return 0;
992 #endif /* CONFIG_SMP */
995 static unsigned short fcstab[256] = {
996 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
997 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
998 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
999 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1000 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1001 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1002 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1003 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1004 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1005 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1006 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1007 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1008 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1009 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1010 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1011 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1012 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1013 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1014 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1015 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1016 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1017 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1018 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1019 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1020 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1021 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1022 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1023 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1024 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1025 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1026 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1027 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1030 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1032 static void
1033 csum(void)
1035 unsigned int i;
1036 unsigned short fcs;
1037 unsigned char v;
1039 if (!scanhex(&adrs))
1040 return;
1041 if (!scanhex(&ncsum))
1042 return;
1043 fcs = 0xffff;
1044 for (i = 0; i < ncsum; ++i) {
1045 if (mread(adrs+i, &v, 1) == 0) {
1046 printf("csum stopped at %x\n", adrs+i);
1047 break;
1049 fcs = FCS(fcs, v);
1051 printf("%x\n", fcs);
1055 * Check if this is a suitable place to put a breakpoint.
1057 static long check_bp_loc(unsigned long addr)
1059 unsigned int instr;
1061 addr &= ~3;
1062 if (!is_kernel_addr(addr)) {
1063 printf("Breakpoints may only be placed at kernel addresses\n");
1064 return 0;
1066 if (!mread(addr, &instr, sizeof(instr))) {
1067 printf("Can't read instruction at address %lx\n", addr);
1068 return 0;
1070 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1071 printf("Breakpoints may not be placed on mtmsrd or rfid "
1072 "instructions\n");
1073 return 0;
1075 return 1;
1078 static char *breakpoint_help_string =
1079 "Breakpoint command usage:\n"
1080 "b show breakpoints\n"
1081 "b <addr> [cnt] set breakpoint at given instr addr\n"
1082 "bc clear all breakpoints\n"
1083 "bc <n/addr> clear breakpoint number n or at addr\n"
1084 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1085 "bd <addr> [cnt] set hardware data breakpoint\n"
1088 static void
1089 bpt_cmds(void)
1091 int cmd;
1092 unsigned long a;
1093 int mode, i;
1094 struct bpt *bp;
1095 const char badaddr[] = "Only kernel addresses are permitted "
1096 "for breakpoints\n";
1098 cmd = inchar();
1099 switch (cmd) {
1100 #ifndef CONFIG_8xx
1101 case 'd': /* bd - hardware data breakpoint */
1102 mode = 7;
1103 cmd = inchar();
1104 if (cmd == 'r')
1105 mode = 5;
1106 else if (cmd == 'w')
1107 mode = 6;
1108 else
1109 termch = cmd;
1110 dabr.address = 0;
1111 dabr.enabled = 0;
1112 if (scanhex(&dabr.address)) {
1113 if (!is_kernel_addr(dabr.address)) {
1114 printf(badaddr);
1115 break;
1117 dabr.address &= ~7;
1118 dabr.enabled = mode | BP_DABR;
1120 break;
1122 case 'i': /* bi - hardware instr breakpoint */
1123 if (!cpu_has_feature(CPU_FTR_IABR)) {
1124 printf("Hardware instruction breakpoint "
1125 "not supported on this cpu\n");
1126 break;
1128 if (iabr) {
1129 iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1130 iabr = NULL;
1132 if (!scanhex(&a))
1133 break;
1134 if (!check_bp_loc(a))
1135 break;
1136 bp = new_breakpoint(a);
1137 if (bp != NULL) {
1138 bp->enabled |= BP_IABR | BP_IABR_TE;
1139 iabr = bp;
1141 break;
1142 #endif
1144 case 'c':
1145 if (!scanhex(&a)) {
1146 /* clear all breakpoints */
1147 for (i = 0; i < NBPTS; ++i)
1148 bpts[i].enabled = 0;
1149 iabr = NULL;
1150 dabr.enabled = 0;
1151 printf("All breakpoints cleared\n");
1152 break;
1155 if (a <= NBPTS && a >= 1) {
1156 /* assume a breakpoint number */
1157 bp = &bpts[a-1]; /* bp nums are 1 based */
1158 } else {
1159 /* assume a breakpoint address */
1160 bp = at_breakpoint(a);
1161 if (bp == NULL) {
1162 printf("No breakpoint at %x\n", a);
1163 break;
1167 printf("Cleared breakpoint %x (", BP_NUM(bp));
1168 xmon_print_symbol(bp->address, " ", ")\n");
1169 bp->enabled = 0;
1170 break;
1172 default:
1173 termch = cmd;
1174 cmd = skipbl();
1175 if (cmd == '?') {
1176 printf(breakpoint_help_string);
1177 break;
1179 termch = cmd;
1180 if (!scanhex(&a)) {
1181 /* print all breakpoints */
1182 printf(" type address\n");
1183 if (dabr.enabled) {
1184 printf(" data "REG" [", dabr.address);
1185 if (dabr.enabled & 1)
1186 printf("r");
1187 if (dabr.enabled & 2)
1188 printf("w");
1189 printf("]\n");
1191 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1192 if (!bp->enabled)
1193 continue;
1194 printf("%2x %s ", BP_NUM(bp),
1195 (bp->enabled & BP_IABR)? "inst": "trap");
1196 xmon_print_symbol(bp->address, " ", "\n");
1198 break;
1201 if (!check_bp_loc(a))
1202 break;
1203 bp = new_breakpoint(a);
1204 if (bp != NULL)
1205 bp->enabled |= BP_TRAP;
1206 break;
1210 /* Very cheap human name for vector lookup. */
1211 static
1212 const char *getvecname(unsigned long vec)
1214 char *ret;
1216 switch (vec) {
1217 case 0x100: ret = "(System Reset)"; break;
1218 case 0x200: ret = "(Machine Check)"; break;
1219 case 0x300: ret = "(Data Access)"; break;
1220 case 0x380: ret = "(Data SLB Access)"; break;
1221 case 0x400: ret = "(Instruction Access)"; break;
1222 case 0x480: ret = "(Instruction SLB Access)"; break;
1223 case 0x500: ret = "(Hardware Interrupt)"; break;
1224 case 0x600: ret = "(Alignment)"; break;
1225 case 0x700: ret = "(Program Check)"; break;
1226 case 0x800: ret = "(FPU Unavailable)"; break;
1227 case 0x900: ret = "(Decrementer)"; break;
1228 case 0xc00: ret = "(System Call)"; break;
1229 case 0xd00: ret = "(Single Step)"; break;
1230 case 0xf00: ret = "(Performance Monitor)"; break;
1231 case 0xf20: ret = "(Altivec Unavailable)"; break;
1232 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1233 default: ret = "";
1235 return ret;
1238 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1239 unsigned long *endp)
1241 unsigned long size, offset;
1242 const char *name;
1244 *startp = *endp = 0;
1245 if (pc == 0)
1246 return;
1247 if (setjmp(bus_error_jmp) == 0) {
1248 catch_memory_errors = 1;
1249 sync();
1250 name = kallsyms_lookup(pc, &size, &offset, NULL, tmpstr);
1251 if (name != NULL) {
1252 *startp = pc - offset;
1253 *endp = pc - offset + size;
1255 sync();
1257 catch_memory_errors = 0;
1260 static int xmon_depth_to_print = 64;
1262 #define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1263 #define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long))
1265 #ifdef __powerpc64__
1266 #define REGS_OFFSET 0x70
1267 #else
1268 #define REGS_OFFSET 16
1269 #endif
1271 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1272 unsigned long pc)
1274 unsigned long ip;
1275 unsigned long newsp;
1276 unsigned long marker;
1277 int count = 0;
1278 struct pt_regs regs;
1280 do {
1281 if (sp < PAGE_OFFSET) {
1282 if (sp != 0)
1283 printf("SP (%lx) is in userspace\n", sp);
1284 break;
1287 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1288 || !mread(sp, &newsp, sizeof(unsigned long))) {
1289 printf("Couldn't read stack frame at %lx\n", sp);
1290 break;
1294 * For the first stack frame, try to work out if
1295 * LR and/or the saved LR value in the bottommost
1296 * stack frame are valid.
1298 if ((pc | lr) != 0) {
1299 unsigned long fnstart, fnend;
1300 unsigned long nextip;
1301 int printip = 1;
1303 get_function_bounds(pc, &fnstart, &fnend);
1304 nextip = 0;
1305 if (newsp > sp)
1306 mread(newsp + LRSAVE_OFFSET, &nextip,
1307 sizeof(unsigned long));
1308 if (lr == ip) {
1309 if (lr < PAGE_OFFSET
1310 || (fnstart <= lr && lr < fnend))
1311 printip = 0;
1312 } else if (lr == nextip) {
1313 printip = 0;
1314 } else if (lr >= PAGE_OFFSET
1315 && !(fnstart <= lr && lr < fnend)) {
1316 printf("[link register ] ");
1317 xmon_print_symbol(lr, " ", "\n");
1319 if (printip) {
1320 printf("["REG"] ", sp);
1321 xmon_print_symbol(ip, " ", " (unreliable)\n");
1323 pc = lr = 0;
1325 } else {
1326 printf("["REG"] ", sp);
1327 xmon_print_symbol(ip, " ", "\n");
1330 /* Look for "regshere" marker to see if this is
1331 an exception frame. */
1332 if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1333 && marker == STACK_FRAME_REGS_MARKER) {
1334 if (mread(sp + REGS_OFFSET, &regs, sizeof(regs))
1335 != sizeof(regs)) {
1336 printf("Couldn't read registers at %lx\n",
1337 sp + REGS_OFFSET);
1338 break;
1340 printf("--- Exception: %lx %s at ", regs.trap,
1341 getvecname(TRAP(&regs)));
1342 pc = regs.nip;
1343 lr = regs.link;
1344 xmon_print_symbol(pc, " ", "\n");
1347 if (newsp == 0)
1348 break;
1350 sp = newsp;
1351 } while (count++ < xmon_depth_to_print);
1354 static void backtrace(struct pt_regs *excp)
1356 unsigned long sp;
1358 if (scanhex(&sp))
1359 xmon_show_stack(sp, 0, 0);
1360 else
1361 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1362 scannl();
1365 static void print_bug_trap(struct pt_regs *regs)
1367 #ifdef CONFIG_BUG
1368 const struct bug_entry *bug;
1369 unsigned long addr;
1371 if (regs->msr & MSR_PR)
1372 return; /* not in kernel */
1373 addr = regs->nip; /* address of trap instruction */
1374 if (addr < PAGE_OFFSET)
1375 return;
1376 bug = find_bug(regs->nip);
1377 if (bug == NULL)
1378 return;
1379 if (is_warning_bug(bug))
1380 return;
1382 #ifdef CONFIG_DEBUG_BUGVERBOSE
1383 printf("kernel BUG at %s:%u!\n",
1384 bug->file, bug->line);
1385 #else
1386 printf("kernel BUG at %p!\n", (void *)bug->bug_addr);
1387 #endif
1388 #endif /* CONFIG_BUG */
1391 static void excprint(struct pt_regs *fp)
1393 unsigned long trap;
1395 #ifdef CONFIG_SMP
1396 printf("cpu 0x%x: ", smp_processor_id());
1397 #endif /* CONFIG_SMP */
1399 trap = TRAP(fp);
1400 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1401 printf(" pc: ");
1402 xmon_print_symbol(fp->nip, ": ", "\n");
1404 printf(" lr: ", fp->link);
1405 xmon_print_symbol(fp->link, ": ", "\n");
1407 printf(" sp: %lx\n", fp->gpr[1]);
1408 printf(" msr: %lx\n", fp->msr);
1410 if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1411 printf(" dar: %lx\n", fp->dar);
1412 if (trap != 0x380)
1413 printf(" dsisr: %lx\n", fp->dsisr);
1416 printf(" current = 0x%lx\n", current);
1417 #ifdef CONFIG_PPC64
1418 printf(" paca = 0x%lx\n", get_paca());
1419 #endif
1420 if (current) {
1421 printf(" pid = %ld, comm = %s\n",
1422 current->pid, current->comm);
1425 if (trap == 0x700)
1426 print_bug_trap(fp);
1429 static void prregs(struct pt_regs *fp)
1431 int n, trap;
1432 unsigned long base;
1433 struct pt_regs regs;
1435 if (scanhex(&base)) {
1436 if (setjmp(bus_error_jmp) == 0) {
1437 catch_memory_errors = 1;
1438 sync();
1439 regs = *(struct pt_regs *)base;
1440 sync();
1441 __delay(200);
1442 } else {
1443 catch_memory_errors = 0;
1444 printf("*** Error reading registers from "REG"\n",
1445 base);
1446 return;
1448 catch_memory_errors = 0;
1449 fp = &regs;
1452 #ifdef CONFIG_PPC64
1453 if (FULL_REGS(fp)) {
1454 for (n = 0; n < 16; ++n)
1455 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1456 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1457 } else {
1458 for (n = 0; n < 7; ++n)
1459 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1460 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1462 #else
1463 for (n = 0; n < 32; ++n) {
1464 printf("R%.2d = %.8x%s", n, fp->gpr[n],
1465 (n & 3) == 3? "\n": " ");
1466 if (n == 12 && !FULL_REGS(fp)) {
1467 printf("\n");
1468 break;
1471 #endif
1472 printf("pc = ");
1473 xmon_print_symbol(fp->nip, " ", "\n");
1474 printf("lr = ");
1475 xmon_print_symbol(fp->link, " ", "\n");
1476 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
1477 printf("ctr = "REG" xer = "REG" trap = %4lx\n",
1478 fp->ctr, fp->xer, fp->trap);
1479 trap = TRAP(fp);
1480 if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1481 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1484 static void cacheflush(void)
1486 int cmd;
1487 unsigned long nflush;
1489 cmd = inchar();
1490 if (cmd != 'i')
1491 termch = cmd;
1492 scanhex((void *)&adrs);
1493 if (termch != '\n')
1494 termch = 0;
1495 nflush = 1;
1496 scanhex(&nflush);
1497 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1498 if (setjmp(bus_error_jmp) == 0) {
1499 catch_memory_errors = 1;
1500 sync();
1502 if (cmd != 'i') {
1503 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1504 cflush((void *) adrs);
1505 } else {
1506 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1507 cinval((void *) adrs);
1509 sync();
1510 /* wait a little while to see if we get a machine check */
1511 __delay(200);
1513 catch_memory_errors = 0;
1516 static unsigned long
1517 read_spr(int n)
1519 unsigned int instrs[2];
1520 unsigned long (*code)(void);
1521 unsigned long ret = -1UL;
1522 #ifdef CONFIG_PPC64
1523 unsigned long opd[3];
1525 opd[0] = (unsigned long)instrs;
1526 opd[1] = 0;
1527 opd[2] = 0;
1528 code = (unsigned long (*)(void)) opd;
1529 #else
1530 code = (unsigned long (*)(void)) instrs;
1531 #endif
1533 /* mfspr r3,n; blr */
1534 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1535 instrs[1] = 0x4e800020;
1536 store_inst(instrs);
1537 store_inst(instrs+1);
1539 if (setjmp(bus_error_jmp) == 0) {
1540 catch_memory_errors = 1;
1541 sync();
1543 ret = code();
1545 sync();
1546 /* wait a little while to see if we get a machine check */
1547 __delay(200);
1548 n = size;
1551 return ret;
1554 static void
1555 write_spr(int n, unsigned long val)
1557 unsigned int instrs[2];
1558 unsigned long (*code)(unsigned long);
1559 #ifdef CONFIG_PPC64
1560 unsigned long opd[3];
1562 opd[0] = (unsigned long)instrs;
1563 opd[1] = 0;
1564 opd[2] = 0;
1565 code = (unsigned long (*)(unsigned long)) opd;
1566 #else
1567 code = (unsigned long (*)(unsigned long)) instrs;
1568 #endif
1570 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1571 instrs[1] = 0x4e800020;
1572 store_inst(instrs);
1573 store_inst(instrs+1);
1575 if (setjmp(bus_error_jmp) == 0) {
1576 catch_memory_errors = 1;
1577 sync();
1579 code(val);
1581 sync();
1582 /* wait a little while to see if we get a machine check */
1583 __delay(200);
1584 n = size;
1588 static unsigned long regno;
1589 extern char exc_prolog;
1590 extern char dec_exc;
1592 static void super_regs(void)
1594 int cmd;
1595 unsigned long val;
1597 cmd = skipbl();
1598 if (cmd == '\n') {
1599 unsigned long sp, toc;
1600 asm("mr %0,1" : "=r" (sp) :);
1601 asm("mr %0,2" : "=r" (toc) :);
1603 printf("msr = "REG" sprg0= "REG"\n",
1604 mfmsr(), mfspr(SPRN_SPRG0));
1605 printf("pvr = "REG" sprg1= "REG"\n",
1606 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
1607 printf("dec = "REG" sprg2= "REG"\n",
1608 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1609 printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1610 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
1611 #ifdef CONFIG_PPC_ISERIES
1612 if (firmware_has_feature(FW_FEATURE_ISERIES)) {
1613 struct paca_struct *ptrPaca;
1614 struct lppaca *ptrLpPaca;
1616 /* Dump out relevant Paca data areas. */
1617 printf("Paca: \n");
1618 ptrPaca = get_paca();
1620 printf(" Local Processor Control Area (LpPaca): \n");
1621 ptrLpPaca = ptrPaca->lppaca_ptr;
1622 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1623 ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
1624 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1625 ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
1626 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
1628 #endif
1630 return;
1633 scanhex(&regno);
1634 switch (cmd) {
1635 case 'w':
1636 val = read_spr(regno);
1637 scanhex(&val);
1638 write_spr(regno, val);
1639 /* fall through */
1640 case 'r':
1641 printf("spr %lx = %lx\n", regno, read_spr(regno));
1642 break;
1644 scannl();
1648 * Stuff for reading and writing memory safely
1650 static int
1651 mread(unsigned long adrs, void *buf, int size)
1653 volatile int n;
1654 char *p, *q;
1656 n = 0;
1657 if (setjmp(bus_error_jmp) == 0) {
1658 catch_memory_errors = 1;
1659 sync();
1660 p = (char *)adrs;
1661 q = (char *)buf;
1662 switch (size) {
1663 case 2:
1664 *(u16 *)q = *(u16 *)p;
1665 break;
1666 case 4:
1667 *(u32 *)q = *(u32 *)p;
1668 break;
1669 case 8:
1670 *(u64 *)q = *(u64 *)p;
1671 break;
1672 default:
1673 for( ; n < size; ++n) {
1674 *q++ = *p++;
1675 sync();
1678 sync();
1679 /* wait a little while to see if we get a machine check */
1680 __delay(200);
1681 n = size;
1683 catch_memory_errors = 0;
1684 return n;
1687 static int
1688 mwrite(unsigned long adrs, void *buf, int size)
1690 volatile int n;
1691 char *p, *q;
1693 n = 0;
1694 if (setjmp(bus_error_jmp) == 0) {
1695 catch_memory_errors = 1;
1696 sync();
1697 p = (char *) adrs;
1698 q = (char *) buf;
1699 switch (size) {
1700 case 2:
1701 *(u16 *)p = *(u16 *)q;
1702 break;
1703 case 4:
1704 *(u32 *)p = *(u32 *)q;
1705 break;
1706 case 8:
1707 *(u64 *)p = *(u64 *)q;
1708 break;
1709 default:
1710 for ( ; n < size; ++n) {
1711 *p++ = *q++;
1712 sync();
1715 sync();
1716 /* wait a little while to see if we get a machine check */
1717 __delay(200);
1718 n = size;
1719 } else {
1720 printf("*** Error writing address %x\n", adrs + n);
1722 catch_memory_errors = 0;
1723 return n;
1726 static int fault_type;
1727 static int fault_except;
1728 static char *fault_chars[] = { "--", "**", "##" };
1730 static int handle_fault(struct pt_regs *regs)
1732 fault_except = TRAP(regs);
1733 switch (TRAP(regs)) {
1734 case 0x200:
1735 fault_type = 0;
1736 break;
1737 case 0x300:
1738 case 0x380:
1739 fault_type = 1;
1740 break;
1741 default:
1742 fault_type = 2;
1745 longjmp(bus_error_jmp, 1);
1747 return 0;
1750 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1752 static void
1753 byterev(unsigned char *val, int size)
1755 int t;
1757 switch (size) {
1758 case 2:
1759 SWAP(val[0], val[1], t);
1760 break;
1761 case 4:
1762 SWAP(val[0], val[3], t);
1763 SWAP(val[1], val[2], t);
1764 break;
1765 case 8: /* is there really any use for this? */
1766 SWAP(val[0], val[7], t);
1767 SWAP(val[1], val[6], t);
1768 SWAP(val[2], val[5], t);
1769 SWAP(val[3], val[4], t);
1770 break;
1774 static int brev;
1775 static int mnoread;
1777 static char *memex_help_string =
1778 "Memory examine command usage:\n"
1779 "m [addr] [flags] examine/change memory\n"
1780 " addr is optional. will start where left off.\n"
1781 " flags may include chars from this set:\n"
1782 " b modify by bytes (default)\n"
1783 " w modify by words (2 byte)\n"
1784 " l modify by longs (4 byte)\n"
1785 " d modify by doubleword (8 byte)\n"
1786 " r toggle reverse byte order mode\n"
1787 " n do not read memory (for i/o spaces)\n"
1788 " . ok to read (default)\n"
1789 "NOTE: flags are saved as defaults\n"
1792 static char *memex_subcmd_help_string =
1793 "Memory examine subcommands:\n"
1794 " hexval write this val to current location\n"
1795 " 'string' write chars from string to this location\n"
1796 " ' increment address\n"
1797 " ^ decrement address\n"
1798 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1799 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1800 " ` clear no-read flag\n"
1801 " ; stay at this addr\n"
1802 " v change to byte mode\n"
1803 " w change to word (2 byte) mode\n"
1804 " l change to long (4 byte) mode\n"
1805 " u change to doubleword (8 byte) mode\n"
1806 " m addr change current addr\n"
1807 " n toggle no-read flag\n"
1808 " r toggle byte reverse flag\n"
1809 " < count back up count bytes\n"
1810 " > count skip forward count bytes\n"
1811 " x exit this mode\n"
1814 static void
1815 memex(void)
1817 int cmd, inc, i, nslash;
1818 unsigned long n;
1819 unsigned char val[16];
1821 scanhex((void *)&adrs);
1822 cmd = skipbl();
1823 if (cmd == '?') {
1824 printf(memex_help_string);
1825 return;
1826 } else {
1827 termch = cmd;
1829 last_cmd = "m\n";
1830 while ((cmd = skipbl()) != '\n') {
1831 switch( cmd ){
1832 case 'b': size = 1; break;
1833 case 'w': size = 2; break;
1834 case 'l': size = 4; break;
1835 case 'd': size = 8; break;
1836 case 'r': brev = !brev; break;
1837 case 'n': mnoread = 1; break;
1838 case '.': mnoread = 0; break;
1841 if( size <= 0 )
1842 size = 1;
1843 else if( size > 8 )
1844 size = 8;
1845 for(;;){
1846 if (!mnoread)
1847 n = mread(adrs, val, size);
1848 printf(REG"%c", adrs, brev? 'r': ' ');
1849 if (!mnoread) {
1850 if (brev)
1851 byterev(val, size);
1852 putchar(' ');
1853 for (i = 0; i < n; ++i)
1854 printf("%.2x", val[i]);
1855 for (; i < size; ++i)
1856 printf("%s", fault_chars[fault_type]);
1858 putchar(' ');
1859 inc = size;
1860 nslash = 0;
1861 for(;;){
1862 if( scanhex(&n) ){
1863 for (i = 0; i < size; ++i)
1864 val[i] = n >> (i * 8);
1865 if (!brev)
1866 byterev(val, size);
1867 mwrite(adrs, val, size);
1868 inc = size;
1870 cmd = skipbl();
1871 if (cmd == '\n')
1872 break;
1873 inc = 0;
1874 switch (cmd) {
1875 case '\'':
1876 for(;;){
1877 n = inchar();
1878 if( n == '\\' )
1879 n = bsesc();
1880 else if( n == '\'' )
1881 break;
1882 for (i = 0; i < size; ++i)
1883 val[i] = n >> (i * 8);
1884 if (!brev)
1885 byterev(val, size);
1886 mwrite(adrs, val, size);
1887 adrs += size;
1889 adrs -= size;
1890 inc = size;
1891 break;
1892 case ',':
1893 adrs += size;
1894 break;
1895 case '.':
1896 mnoread = 0;
1897 break;
1898 case ';':
1899 break;
1900 case 'x':
1901 case EOF:
1902 scannl();
1903 return;
1904 case 'b':
1905 case 'v':
1906 size = 1;
1907 break;
1908 case 'w':
1909 size = 2;
1910 break;
1911 case 'l':
1912 size = 4;
1913 break;
1914 case 'u':
1915 size = 8;
1916 break;
1917 case '^':
1918 adrs -= size;
1919 break;
1920 break;
1921 case '/':
1922 if (nslash > 0)
1923 adrs -= 1 << nslash;
1924 else
1925 nslash = 0;
1926 nslash += 4;
1927 adrs += 1 << nslash;
1928 break;
1929 case '\\':
1930 if (nslash < 0)
1931 adrs += 1 << -nslash;
1932 else
1933 nslash = 0;
1934 nslash -= 4;
1935 adrs -= 1 << -nslash;
1936 break;
1937 case 'm':
1938 scanhex((void *)&adrs);
1939 break;
1940 case 'n':
1941 mnoread = 1;
1942 break;
1943 case 'r':
1944 brev = !brev;
1945 break;
1946 case '<':
1947 n = size;
1948 scanhex(&n);
1949 adrs -= n;
1950 break;
1951 case '>':
1952 n = size;
1953 scanhex(&n);
1954 adrs += n;
1955 break;
1956 case '?':
1957 printf(memex_subcmd_help_string);
1958 break;
1961 adrs += inc;
1965 static int
1966 bsesc(void)
1968 int c;
1970 c = inchar();
1971 switch( c ){
1972 case 'n': c = '\n'; break;
1973 case 'r': c = '\r'; break;
1974 case 'b': c = '\b'; break;
1975 case 't': c = '\t'; break;
1977 return c;
1980 static void xmon_rawdump (unsigned long adrs, long ndump)
1982 long n, m, r, nr;
1983 unsigned char temp[16];
1985 for (n = ndump; n > 0;) {
1986 r = n < 16? n: 16;
1987 nr = mread(adrs, temp, r);
1988 adrs += nr;
1989 for (m = 0; m < r; ++m) {
1990 if (m < nr)
1991 printf("%.2x", temp[m]);
1992 else
1993 printf("%s", fault_chars[fault_type]);
1995 n -= r;
1996 if (nr < r)
1997 break;
1999 printf("\n");
2002 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
2003 || ('a' <= (c) && (c) <= 'f') \
2004 || ('A' <= (c) && (c) <= 'F'))
2005 static void
2006 dump(void)
2008 int c;
2010 c = inchar();
2011 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
2012 termch = c;
2013 scanhex((void *)&adrs);
2014 if (termch != '\n')
2015 termch = 0;
2016 if (c == 'i') {
2017 scanhex(&nidump);
2018 if (nidump == 0)
2019 nidump = 16;
2020 else if (nidump > MAX_DUMP)
2021 nidump = MAX_DUMP;
2022 adrs += ppc_inst_dump(adrs, nidump, 1);
2023 last_cmd = "di\n";
2024 } else if (c == 'l') {
2025 dump_log_buf();
2026 } else if (c == 'r') {
2027 scanhex(&ndump);
2028 if (ndump == 0)
2029 ndump = 64;
2030 xmon_rawdump(adrs, ndump);
2031 adrs += ndump;
2032 last_cmd = "dr\n";
2033 } else {
2034 scanhex(&ndump);
2035 if (ndump == 0)
2036 ndump = 64;
2037 else if (ndump > MAX_DUMP)
2038 ndump = MAX_DUMP;
2039 prdump(adrs, ndump);
2040 adrs += ndump;
2041 last_cmd = "d\n";
2045 static void
2046 prdump(unsigned long adrs, long ndump)
2048 long n, m, c, r, nr;
2049 unsigned char temp[16];
2051 for (n = ndump; n > 0;) {
2052 printf(REG, adrs);
2053 putchar(' ');
2054 r = n < 16? n: 16;
2055 nr = mread(adrs, temp, r);
2056 adrs += nr;
2057 for (m = 0; m < r; ++m) {
2058 if ((m & (sizeof(long) - 1)) == 0 && m > 0)
2059 putchar(' ');
2060 if (m < nr)
2061 printf("%.2x", temp[m]);
2062 else
2063 printf("%s", fault_chars[fault_type]);
2065 for (; m < 16; ++m) {
2066 if ((m & (sizeof(long) - 1)) == 0)
2067 putchar(' ');
2068 printf(" ");
2070 printf(" |");
2071 for (m = 0; m < r; ++m) {
2072 if (m < nr) {
2073 c = temp[m];
2074 putchar(' ' <= c && c <= '~'? c: '.');
2075 } else
2076 putchar(' ');
2078 n -= r;
2079 for (; m < 16; ++m)
2080 putchar(' ');
2081 printf("|\n");
2082 if (nr < r)
2083 break;
2087 typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr);
2089 static int
2090 generic_inst_dump(unsigned long adr, long count, int praddr,
2091 instruction_dump_func dump_func)
2093 int nr, dotted;
2094 unsigned long first_adr;
2095 unsigned long inst, last_inst = 0;
2096 unsigned char val[4];
2098 dotted = 0;
2099 for (first_adr = adr; count > 0; --count, adr += 4) {
2100 nr = mread(adr, val, 4);
2101 if (nr == 0) {
2102 if (praddr) {
2103 const char *x = fault_chars[fault_type];
2104 printf(REG" %s%s%s%s\n", adr, x, x, x, x);
2106 break;
2108 inst = GETWORD(val);
2109 if (adr > first_adr && inst == last_inst) {
2110 if (!dotted) {
2111 printf(" ...\n");
2112 dotted = 1;
2114 continue;
2116 dotted = 0;
2117 last_inst = inst;
2118 if (praddr)
2119 printf(REG" %.8x", adr, inst);
2120 printf("\t");
2121 dump_func(inst, adr);
2122 printf("\n");
2124 return adr - first_adr;
2127 static int
2128 ppc_inst_dump(unsigned long adr, long count, int praddr)
2130 return generic_inst_dump(adr, count, praddr, print_insn_powerpc);
2133 void
2134 print_address(unsigned long addr)
2136 xmon_print_symbol(addr, "\t# ", "");
2139 void
2140 dump_log_buf(void)
2142 const unsigned long size = 128;
2143 unsigned long end, addr;
2144 unsigned char buf[size + 1];
2146 addr = 0;
2147 buf[size] = '\0';
2149 if (setjmp(bus_error_jmp) != 0) {
2150 printf("Unable to lookup symbol __log_buf!\n");
2151 return;
2154 catch_memory_errors = 1;
2155 sync();
2156 addr = kallsyms_lookup_name("__log_buf");
2158 if (! addr)
2159 printf("Symbol __log_buf not found!\n");
2160 else {
2161 end = addr + (1 << CONFIG_LOG_BUF_SHIFT);
2162 while (addr < end) {
2163 if (! mread(addr, buf, size)) {
2164 printf("Can't read memory at address 0x%lx\n", addr);
2165 break;
2168 printf("%s", buf);
2170 if (strlen(buf) < size)
2171 break;
2173 addr += size;
2177 sync();
2178 /* wait a little while to see if we get a machine check */
2179 __delay(200);
2180 catch_memory_errors = 0;
2184 * Memory operations - move, set, print differences
2186 static unsigned long mdest; /* destination address */
2187 static unsigned long msrc; /* source address */
2188 static unsigned long mval; /* byte value to set memory to */
2189 static unsigned long mcount; /* # bytes to affect */
2190 static unsigned long mdiffs; /* max # differences to print */
2192 static void
2193 memops(int cmd)
2195 scanhex((void *)&mdest);
2196 if( termch != '\n' )
2197 termch = 0;
2198 scanhex((void *)(cmd == 's'? &mval: &msrc));
2199 if( termch != '\n' )
2200 termch = 0;
2201 scanhex((void *)&mcount);
2202 switch( cmd ){
2203 case 'm':
2204 memmove((void *)mdest, (void *)msrc, mcount);
2205 break;
2206 case 's':
2207 memset((void *)mdest, mval, mcount);
2208 break;
2209 case 'd':
2210 if( termch != '\n' )
2211 termch = 0;
2212 scanhex((void *)&mdiffs);
2213 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2214 break;
2218 static void
2219 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2221 unsigned n, prt;
2223 prt = 0;
2224 for( n = nb; n > 0; --n )
2225 if( *p1++ != *p2++ )
2226 if( ++prt <= maxpr )
2227 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2228 p1[-1], p2 - 1, p2[-1]);
2229 if( prt > maxpr )
2230 printf("Total of %d differences\n", prt);
2233 static unsigned mend;
2234 static unsigned mask;
2236 static void
2237 memlocate(void)
2239 unsigned a, n;
2240 unsigned char val[4];
2242 last_cmd = "ml";
2243 scanhex((void *)&mdest);
2244 if (termch != '\n') {
2245 termch = 0;
2246 scanhex((void *)&mend);
2247 if (termch != '\n') {
2248 termch = 0;
2249 scanhex((void *)&mval);
2250 mask = ~0;
2251 if (termch != '\n') termch = 0;
2252 scanhex((void *)&mask);
2255 n = 0;
2256 for (a = mdest; a < mend; a += 4) {
2257 if (mread(a, val, 4) == 4
2258 && ((GETWORD(val) ^ mval) & mask) == 0) {
2259 printf("%.16x: %.16x\n", a, GETWORD(val));
2260 if (++n >= 10)
2261 break;
2266 static unsigned long mskip = 0x1000;
2267 static unsigned long mlim = 0xffffffff;
2269 static void
2270 memzcan(void)
2272 unsigned char v;
2273 unsigned a;
2274 int ok, ook;
2276 scanhex(&mdest);
2277 if (termch != '\n') termch = 0;
2278 scanhex(&mskip);
2279 if (termch != '\n') termch = 0;
2280 scanhex(&mlim);
2281 ook = 0;
2282 for (a = mdest; a < mlim; a += mskip) {
2283 ok = mread(a, &v, 1);
2284 if (ok && !ook) {
2285 printf("%.8x .. ", a);
2286 } else if (!ok && ook)
2287 printf("%.8x\n", a - mskip);
2288 ook = ok;
2289 if (a + mskip < a)
2290 break;
2292 if (ook)
2293 printf("%.8x\n", a - mskip);
2296 static void proccall(void)
2298 unsigned long args[8];
2299 unsigned long ret;
2300 int i;
2301 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2302 unsigned long, unsigned long, unsigned long,
2303 unsigned long, unsigned long, unsigned long);
2304 callfunc_t func;
2306 if (!scanhex(&adrs))
2307 return;
2308 if (termch != '\n')
2309 termch = 0;
2310 for (i = 0; i < 8; ++i)
2311 args[i] = 0;
2312 for (i = 0; i < 8; ++i) {
2313 if (!scanhex(&args[i]) || termch == '\n')
2314 break;
2315 termch = 0;
2317 func = (callfunc_t) adrs;
2318 ret = 0;
2319 if (setjmp(bus_error_jmp) == 0) {
2320 catch_memory_errors = 1;
2321 sync();
2322 ret = func(args[0], args[1], args[2], args[3],
2323 args[4], args[5], args[6], args[7]);
2324 sync();
2325 printf("return value is %x\n", ret);
2326 } else {
2327 printf("*** %x exception occurred\n", fault_except);
2329 catch_memory_errors = 0;
2332 /* Input scanning routines */
2334 skipbl(void)
2336 int c;
2338 if( termch != 0 ){
2339 c = termch;
2340 termch = 0;
2341 } else
2342 c = inchar();
2343 while( c == ' ' || c == '\t' )
2344 c = inchar();
2345 return c;
2348 #define N_PTREGS 44
2349 static char *regnames[N_PTREGS] = {
2350 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2351 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2352 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2353 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2354 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2355 #ifdef CONFIG_PPC64
2356 "softe",
2357 #else
2358 "mq",
2359 #endif
2360 "trap", "dar", "dsisr", "res"
2364 scanhex(unsigned long *vp)
2366 int c, d;
2367 unsigned long v;
2369 c = skipbl();
2370 if (c == '%') {
2371 /* parse register name */
2372 char regname[8];
2373 int i;
2375 for (i = 0; i < sizeof(regname) - 1; ++i) {
2376 c = inchar();
2377 if (!isalnum(c)) {
2378 termch = c;
2379 break;
2381 regname[i] = c;
2383 regname[i] = 0;
2384 for (i = 0; i < N_PTREGS; ++i) {
2385 if (strcmp(regnames[i], regname) == 0) {
2386 if (xmon_regs == NULL) {
2387 printf("regs not available\n");
2388 return 0;
2390 *vp = ((unsigned long *)xmon_regs)[i];
2391 return 1;
2394 printf("invalid register name '%%%s'\n", regname);
2395 return 0;
2398 /* skip leading "0x" if any */
2400 if (c == '0') {
2401 c = inchar();
2402 if (c == 'x') {
2403 c = inchar();
2404 } else {
2405 d = hexdigit(c);
2406 if (d == EOF) {
2407 termch = c;
2408 *vp = 0;
2409 return 1;
2412 } else if (c == '$') {
2413 int i;
2414 for (i=0; i<63; i++) {
2415 c = inchar();
2416 if (isspace(c)) {
2417 termch = c;
2418 break;
2420 tmpstr[i] = c;
2422 tmpstr[i++] = 0;
2423 *vp = 0;
2424 if (setjmp(bus_error_jmp) == 0) {
2425 catch_memory_errors = 1;
2426 sync();
2427 *vp = kallsyms_lookup_name(tmpstr);
2428 sync();
2430 catch_memory_errors = 0;
2431 if (!(*vp)) {
2432 printf("unknown symbol '%s'\n", tmpstr);
2433 return 0;
2435 return 1;
2438 d = hexdigit(c);
2439 if (d == EOF) {
2440 termch = c;
2441 return 0;
2443 v = 0;
2444 do {
2445 v = (v << 4) + d;
2446 c = inchar();
2447 d = hexdigit(c);
2448 } while (d != EOF);
2449 termch = c;
2450 *vp = v;
2451 return 1;
2454 static void
2455 scannl(void)
2457 int c;
2459 c = termch;
2460 termch = 0;
2461 while( c != '\n' )
2462 c = inchar();
2465 static int hexdigit(int c)
2467 if( '0' <= c && c <= '9' )
2468 return c - '0';
2469 if( 'A' <= c && c <= 'F' )
2470 return c - ('A' - 10);
2471 if( 'a' <= c && c <= 'f' )
2472 return c - ('a' - 10);
2473 return EOF;
2476 void
2477 getstring(char *s, int size)
2479 int c;
2481 c = skipbl();
2482 do {
2483 if( size > 1 ){
2484 *s++ = c;
2485 --size;
2487 c = inchar();
2488 } while( c != ' ' && c != '\t' && c != '\n' );
2489 termch = c;
2490 *s = 0;
2493 static char line[256];
2494 static char *lineptr;
2496 static void
2497 flush_input(void)
2499 lineptr = NULL;
2502 static int
2503 inchar(void)
2505 if (lineptr == NULL || *lineptr == 0) {
2506 if (xmon_gets(line, sizeof(line)) == NULL) {
2507 lineptr = NULL;
2508 return EOF;
2510 lineptr = line;
2512 return *lineptr++;
2515 static void
2516 take_input(char *str)
2518 lineptr = str;
2522 static void
2523 symbol_lookup(void)
2525 int type = inchar();
2526 unsigned long addr;
2527 static char tmp[64];
2529 switch (type) {
2530 case 'a':
2531 if (scanhex(&addr))
2532 xmon_print_symbol(addr, ": ", "\n");
2533 termch = 0;
2534 break;
2535 case 's':
2536 getstring(tmp, 64);
2537 if (setjmp(bus_error_jmp) == 0) {
2538 catch_memory_errors = 1;
2539 sync();
2540 addr = kallsyms_lookup_name(tmp);
2541 if (addr)
2542 printf("%s: %lx\n", tmp, addr);
2543 else
2544 printf("Symbol '%s' not found.\n", tmp);
2545 sync();
2547 catch_memory_errors = 0;
2548 termch = 0;
2549 break;
2554 /* Print an address in numeric and symbolic form (if possible) */
2555 static void xmon_print_symbol(unsigned long address, const char *mid,
2556 const char *after)
2558 char *modname;
2559 const char *name = NULL;
2560 unsigned long offset, size;
2562 printf(REG, address);
2563 if (setjmp(bus_error_jmp) == 0) {
2564 catch_memory_errors = 1;
2565 sync();
2566 name = kallsyms_lookup(address, &size, &offset, &modname,
2567 tmpstr);
2568 sync();
2569 /* wait a little while to see if we get a machine check */
2570 __delay(200);
2573 catch_memory_errors = 0;
2575 if (name) {
2576 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2577 if (modname)
2578 printf(" [%s]", modname);
2580 printf("%s", after);
2583 #ifdef CONFIG_PPC_BOOK3S_64
2584 static void dump_slb(void)
2586 int i;
2587 unsigned long esid,vsid,valid;
2588 unsigned long llp;
2590 printf("SLB contents of cpu %x\n", smp_processor_id());
2592 for (i = 0; i < mmu_slb_size; i++) {
2593 asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i));
2594 asm volatile("slbmfev %0,%1" : "=r" (vsid) : "r" (i));
2595 valid = (esid & SLB_ESID_V);
2596 if (valid | esid | vsid) {
2597 printf("%02d %016lx %016lx", i, esid, vsid);
2598 if (valid) {
2599 llp = vsid & SLB_VSID_LLP;
2600 if (vsid & SLB_VSID_B_1T) {
2601 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
2602 GET_ESID_1T(esid),
2603 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T,
2604 llp);
2605 } else {
2606 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
2607 GET_ESID(esid),
2608 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT,
2609 llp);
2611 } else
2612 printf("\n");
2617 static void dump_stab(void)
2619 int i;
2620 unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2622 printf("Segment table contents of cpu %x\n", smp_processor_id());
2624 for (i = 0; i < PAGE_SIZE/16; i++) {
2625 unsigned long a, b;
2627 a = *tmp++;
2628 b = *tmp++;
2630 if (a || b) {
2631 printf("%03d %016lx ", i, a);
2632 printf("%016lx\n", b);
2637 void dump_segments(void)
2639 if (cpu_has_feature(CPU_FTR_SLB))
2640 dump_slb();
2641 else
2642 dump_stab();
2644 #endif
2646 #ifdef CONFIG_PPC_STD_MMU_32
2647 void dump_segments(void)
2649 int i;
2651 printf("sr0-15 =");
2652 for (i = 0; i < 16; ++i)
2653 printf(" %x", mfsrin(i));
2654 printf("\n");
2656 #endif
2658 #ifdef CONFIG_44x
2659 static void dump_tlb_44x(void)
2661 int i;
2663 for (i = 0; i < PPC44x_TLB_SIZE; i++) {
2664 unsigned long w0,w1,w2;
2665 asm volatile("tlbre %0,%1,0" : "=r" (w0) : "r" (i));
2666 asm volatile("tlbre %0,%1,1" : "=r" (w1) : "r" (i));
2667 asm volatile("tlbre %0,%1,2" : "=r" (w2) : "r" (i));
2668 printf("[%02x] %08x %08x %08x ", i, w0, w1, w2);
2669 if (w0 & PPC44x_TLB_VALID) {
2670 printf("V %08x -> %01x%08x %c%c%c%c%c",
2671 w0 & PPC44x_TLB_EPN_MASK,
2672 w1 & PPC44x_TLB_ERPN_MASK,
2673 w1 & PPC44x_TLB_RPN_MASK,
2674 (w2 & PPC44x_TLB_W) ? 'W' : 'w',
2675 (w2 & PPC44x_TLB_I) ? 'I' : 'i',
2676 (w2 & PPC44x_TLB_M) ? 'M' : 'm',
2677 (w2 & PPC44x_TLB_G) ? 'G' : 'g',
2678 (w2 & PPC44x_TLB_E) ? 'E' : 'e');
2680 printf("\n");
2683 #endif /* CONFIG_44x */
2685 static void xmon_init(int enable)
2687 #ifdef CONFIG_PPC_ISERIES
2688 if (firmware_has_feature(FW_FEATURE_ISERIES))
2689 return;
2690 #endif
2691 if (enable) {
2692 __debugger = xmon;
2693 __debugger_ipi = xmon_ipi;
2694 __debugger_bpt = xmon_bpt;
2695 __debugger_sstep = xmon_sstep;
2696 __debugger_iabr_match = xmon_iabr_match;
2697 __debugger_dabr_match = xmon_dabr_match;
2698 __debugger_fault_handler = xmon_fault_handler;
2699 } else {
2700 __debugger = NULL;
2701 __debugger_ipi = NULL;
2702 __debugger_bpt = NULL;
2703 __debugger_sstep = NULL;
2704 __debugger_iabr_match = NULL;
2705 __debugger_dabr_match = NULL;
2706 __debugger_fault_handler = NULL;
2708 xmon_map_scc();
2711 #ifdef CONFIG_MAGIC_SYSRQ
2712 static void sysrq_handle_xmon(int key, struct tty_struct *tty)
2714 /* ensure xmon is enabled */
2715 xmon_init(1);
2716 debugger(get_irq_regs());
2719 static struct sysrq_key_op sysrq_xmon_op =
2721 .handler = sysrq_handle_xmon,
2722 .help_msg = "Xmon",
2723 .action_msg = "Entering xmon",
2726 static int __init setup_xmon_sysrq(void)
2728 #ifdef CONFIG_PPC_ISERIES
2729 if (firmware_has_feature(FW_FEATURE_ISERIES))
2730 return 0;
2731 #endif
2732 register_sysrq_key('x', &sysrq_xmon_op);
2733 return 0;
2735 __initcall(setup_xmon_sysrq);
2736 #endif /* CONFIG_MAGIC_SYSRQ */
2738 static int __initdata xmon_early, xmon_off;
2740 static int __init early_parse_xmon(char *p)
2742 if (!p || strncmp(p, "early", 5) == 0) {
2743 /* just "xmon" is equivalent to "xmon=early" */
2744 xmon_init(1);
2745 xmon_early = 1;
2746 } else if (strncmp(p, "on", 2) == 0)
2747 xmon_init(1);
2748 else if (strncmp(p, "off", 3) == 0)
2749 xmon_off = 1;
2750 else if (strncmp(p, "nobt", 4) == 0)
2751 xmon_no_auto_backtrace = 1;
2752 else
2753 return 1;
2755 return 0;
2757 early_param("xmon", early_parse_xmon);
2759 void __init xmon_setup(void)
2761 #ifdef CONFIG_XMON_DEFAULT
2762 if (!xmon_off)
2763 xmon_init(1);
2764 #endif
2765 if (xmon_early)
2766 debugger(NULL);
2769 #ifdef CONFIG_SPU_BASE
2771 struct spu_info {
2772 struct spu *spu;
2773 u64 saved_mfc_sr1_RW;
2774 u32 saved_spu_runcntl_RW;
2775 unsigned long dump_addr;
2776 u8 stopped_ok;
2779 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
2781 static struct spu_info spu_info[XMON_NUM_SPUS];
2783 void xmon_register_spus(struct list_head *list)
2785 struct spu *spu;
2787 list_for_each_entry(spu, list, full_list) {
2788 if (spu->number >= XMON_NUM_SPUS) {
2789 WARN_ON(1);
2790 continue;
2793 spu_info[spu->number].spu = spu;
2794 spu_info[spu->number].stopped_ok = 0;
2795 spu_info[spu->number].dump_addr = (unsigned long)
2796 spu_info[spu->number].spu->local_store;
2800 static void stop_spus(void)
2802 struct spu *spu;
2803 int i;
2804 u64 tmp;
2806 for (i = 0; i < XMON_NUM_SPUS; i++) {
2807 if (!spu_info[i].spu)
2808 continue;
2810 if (setjmp(bus_error_jmp) == 0) {
2811 catch_memory_errors = 1;
2812 sync();
2814 spu = spu_info[i].spu;
2816 spu_info[i].saved_spu_runcntl_RW =
2817 in_be32(&spu->problem->spu_runcntl_RW);
2819 tmp = spu_mfc_sr1_get(spu);
2820 spu_info[i].saved_mfc_sr1_RW = tmp;
2822 tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
2823 spu_mfc_sr1_set(spu, tmp);
2825 sync();
2826 __delay(200);
2828 spu_info[i].stopped_ok = 1;
2830 printf("Stopped spu %.2d (was %s)\n", i,
2831 spu_info[i].saved_spu_runcntl_RW ?
2832 "running" : "stopped");
2833 } else {
2834 catch_memory_errors = 0;
2835 printf("*** Error stopping spu %.2d\n", i);
2837 catch_memory_errors = 0;
2841 static void restart_spus(void)
2843 struct spu *spu;
2844 int i;
2846 for (i = 0; i < XMON_NUM_SPUS; i++) {
2847 if (!spu_info[i].spu)
2848 continue;
2850 if (!spu_info[i].stopped_ok) {
2851 printf("*** Error, spu %d was not successfully stopped"
2852 ", not restarting\n", i);
2853 continue;
2856 if (setjmp(bus_error_jmp) == 0) {
2857 catch_memory_errors = 1;
2858 sync();
2860 spu = spu_info[i].spu;
2861 spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
2862 out_be32(&spu->problem->spu_runcntl_RW,
2863 spu_info[i].saved_spu_runcntl_RW);
2865 sync();
2866 __delay(200);
2868 printf("Restarted spu %.2d\n", i);
2869 } else {
2870 catch_memory_errors = 0;
2871 printf("*** Error restarting spu %.2d\n", i);
2873 catch_memory_errors = 0;
2877 #define DUMP_WIDTH 23
2878 #define DUMP_VALUE(format, field, value) \
2879 do { \
2880 if (setjmp(bus_error_jmp) == 0) { \
2881 catch_memory_errors = 1; \
2882 sync(); \
2883 printf(" %-*s = "format"\n", DUMP_WIDTH, \
2884 #field, value); \
2885 sync(); \
2886 __delay(200); \
2887 } else { \
2888 catch_memory_errors = 0; \
2889 printf(" %-*s = *** Error reading field.\n", \
2890 DUMP_WIDTH, #field); \
2892 catch_memory_errors = 0; \
2893 } while (0)
2895 #define DUMP_FIELD(obj, format, field) \
2896 DUMP_VALUE(format, field, obj->field)
2898 static void dump_spu_fields(struct spu *spu)
2900 printf("Dumping spu fields at address %p:\n", spu);
2902 DUMP_FIELD(spu, "0x%x", number);
2903 DUMP_FIELD(spu, "%s", name);
2904 DUMP_FIELD(spu, "0x%lx", local_store_phys);
2905 DUMP_FIELD(spu, "0x%p", local_store);
2906 DUMP_FIELD(spu, "0x%lx", ls_size);
2907 DUMP_FIELD(spu, "0x%x", node);
2908 DUMP_FIELD(spu, "0x%lx", flags);
2909 DUMP_FIELD(spu, "%d", class_0_pending);
2910 DUMP_FIELD(spu, "0x%lx", class_0_dar);
2911 DUMP_FIELD(spu, "0x%lx", class_1_dar);
2912 DUMP_FIELD(spu, "0x%lx", class_1_dsisr);
2913 DUMP_FIELD(spu, "0x%lx", irqs[0]);
2914 DUMP_FIELD(spu, "0x%lx", irqs[1]);
2915 DUMP_FIELD(spu, "0x%lx", irqs[2]);
2916 DUMP_FIELD(spu, "0x%x", slb_replace);
2917 DUMP_FIELD(spu, "%d", pid);
2918 DUMP_FIELD(spu, "0x%p", mm);
2919 DUMP_FIELD(spu, "0x%p", ctx);
2920 DUMP_FIELD(spu, "0x%p", rq);
2921 DUMP_FIELD(spu, "0x%p", timestamp);
2922 DUMP_FIELD(spu, "0x%lx", problem_phys);
2923 DUMP_FIELD(spu, "0x%p", problem);
2924 DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
2925 in_be32(&spu->problem->spu_runcntl_RW));
2926 DUMP_VALUE("0x%x", problem->spu_status_R,
2927 in_be32(&spu->problem->spu_status_R));
2928 DUMP_VALUE("0x%x", problem->spu_npc_RW,
2929 in_be32(&spu->problem->spu_npc_RW));
2930 DUMP_FIELD(spu, "0x%p", priv2);
2931 DUMP_FIELD(spu, "0x%p", pdata);
2935 spu_inst_dump(unsigned long adr, long count, int praddr)
2937 return generic_inst_dump(adr, count, praddr, print_insn_spu);
2940 static void dump_spu_ls(unsigned long num, int subcmd)
2942 unsigned long offset, addr, ls_addr;
2944 if (setjmp(bus_error_jmp) == 0) {
2945 catch_memory_errors = 1;
2946 sync();
2947 ls_addr = (unsigned long)spu_info[num].spu->local_store;
2948 sync();
2949 __delay(200);
2950 } else {
2951 catch_memory_errors = 0;
2952 printf("*** Error: accessing spu info for spu %d\n", num);
2953 return;
2955 catch_memory_errors = 0;
2957 if (scanhex(&offset))
2958 addr = ls_addr + offset;
2959 else
2960 addr = spu_info[num].dump_addr;
2962 if (addr >= ls_addr + LS_SIZE) {
2963 printf("*** Error: address outside of local store\n");
2964 return;
2967 switch (subcmd) {
2968 case 'i':
2969 addr += spu_inst_dump(addr, 16, 1);
2970 last_cmd = "sdi\n";
2971 break;
2972 default:
2973 prdump(addr, 64);
2974 addr += 64;
2975 last_cmd = "sd\n";
2976 break;
2979 spu_info[num].dump_addr = addr;
2982 static int do_spu_cmd(void)
2984 static unsigned long num = 0;
2985 int cmd, subcmd = 0;
2987 cmd = inchar();
2988 switch (cmd) {
2989 case 's':
2990 stop_spus();
2991 break;
2992 case 'r':
2993 restart_spus();
2994 break;
2995 case 'd':
2996 subcmd = inchar();
2997 if (isxdigit(subcmd) || subcmd == '\n')
2998 termch = subcmd;
2999 case 'f':
3000 scanhex(&num);
3001 if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
3002 printf("*** Error: invalid spu number\n");
3003 return 0;
3006 switch (cmd) {
3007 case 'f':
3008 dump_spu_fields(spu_info[num].spu);
3009 break;
3010 default:
3011 dump_spu_ls(num, subcmd);
3012 break;
3015 break;
3016 default:
3017 return -1;
3020 return 0;
3022 #else /* ! CONFIG_SPU_BASE */
3023 static int do_spu_cmd(void)
3025 return -1;
3027 #endif