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>
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>
30 #include <asm/machdep.h>
32 #include <asm/processor.h>
33 #include <asm/pgtable.h>
35 #include <asm/mmu_context.h>
36 #include <asm/cputable.h>
38 #include <asm/sstep.h>
39 #include <asm/irq_regs.h>
41 #include <asm/spu_priv1.h>
42 #include <asm/firmware.h>
45 #include <asm/hvcall.h>
47 #include <asm/iseries/it_lp_reg_save.h>
53 #define scanhex xmon_scanhex
54 #define skipbl xmon_skipbl
57 cpumask_t cpus_in_xmon = CPU_MASK_NONE;
58 static unsigned long xmon_taken = 1;
59 static int xmon_owner;
61 #endif /* CONFIG_SMP */
63 static unsigned long in_xmon = 0;
65 static unsigned long adrs;
67 #define MAX_DUMP (128 * 1024)
68 static unsigned long ndump = 64;
69 static unsigned long nidump = 16;
70 static unsigned long ncsum = 4096;
72 static char tmpstr[128];
74 #define JMP_BUF_LEN 23
75 static long bus_error_jmp[JMP_BUF_LEN];
76 static int catch_memory_errors;
77 static long *xmon_fault_jmp[NR_CPUS];
78 #define setjmp xmon_setjmp
79 #define longjmp xmon_longjmp
81 /* Breakpoint stuff */
83 unsigned long address;
84 unsigned int instr[2];
90 /* Bits in bpt.enabled */
91 #define BP_IABR_TE 1 /* IABR translation enabled */
97 static struct bpt bpts[NBPTS];
98 static struct bpt dabr;
99 static struct bpt *iabr;
100 static unsigned bpinstr = 0x7fe00008; /* trap */
102 #define BP_NUM(bp) ((bp) - bpts + 1)
105 static int cmds(struct pt_regs *);
106 static int mread(unsigned long, void *, int);
107 static int mwrite(unsigned long, void *, int);
108 static int handle_fault(struct pt_regs *);
109 static void byterev(unsigned char *, int);
110 static void memex(void);
111 static int bsesc(void);
112 static void dump(void);
113 static void prdump(unsigned long, long);
114 static int ppc_inst_dump(unsigned long, long, int);
115 static void backtrace(struct pt_regs *);
116 static void excprint(struct pt_regs *);
117 static void prregs(struct pt_regs *);
118 static void memops(int);
119 static void memlocate(void);
120 static void memzcan(void);
121 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
123 int scanhex(unsigned long *valp);
124 static void scannl(void);
125 static int hexdigit(int);
126 void getstring(char *, int);
127 static void flush_input(void);
128 static int inchar(void);
129 static void take_input(char *);
130 static unsigned long read_spr(int);
131 static void write_spr(int, unsigned long);
132 static void super_regs(void);
133 static void remove_bpts(void);
134 static void insert_bpts(void);
135 static void remove_cpu_bpts(void);
136 static void insert_cpu_bpts(void);
137 static struct bpt *at_breakpoint(unsigned long pc);
138 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
139 static int do_step(struct pt_regs *);
140 static void bpt_cmds(void);
141 static void cacheflush(void);
142 static int cpu_cmd(void);
143 static void csum(void);
144 static void bootcmds(void);
145 static void proccall(void);
146 void dump_segments(void);
147 static void symbol_lookup(void);
148 static void xmon_show_stack(unsigned long sp, unsigned long lr,
150 static void xmon_print_symbol(unsigned long address, const char *mid,
152 static const char *getvecname(unsigned long vec);
154 static int do_spu_cmd(void);
156 int xmon_no_auto_backtrace;
158 extern void xmon_enter(void);
159 extern void xmon_leave(void);
161 extern long setjmp(long *);
162 extern void longjmp(long *, long);
163 extern void xmon_save_regs(struct pt_regs *);
167 #define REGS_PER_LINE 4
168 #define LAST_VOLATILE 13
171 #define REGS_PER_LINE 8
172 #define LAST_VOLATILE 12
175 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
177 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
178 || ('a' <= (c) && (c) <= 'f') \
179 || ('A' <= (c) && (c) <= 'F'))
180 #define isalnum(c) (('0' <= (c) && (c) <= '9') \
181 || ('a' <= (c) && (c) <= 'z') \
182 || ('A' <= (c) && (c) <= 'Z'))
183 #define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
185 static char *help_string = "\
187 b show breakpoints\n\
188 bd set data breakpoint\n\
189 bi set instruction breakpoint\n\
190 bc clear breakpoint\n"
193 c print cpus stopped in xmon\n\
194 c# try to switch to cpu number h (in hex)\n"
199 di dump instructions\n\
200 df dump float values\n\
201 dd dump double values\n\
202 dr dump stream of raw bytes\n\
203 e print exception information\n\
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\
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"
224 " S print special registers\n\
226 x exit monitor and recover\n\
227 X exit monitor and dont recover\n"
229 " u dump segment table or SLB\n"
231 #ifdef CONFIG_PPC_STD_MMU_32
232 " u dump segment registers\n"
239 static struct pt_regs *xmon_regs;
241 static inline void sync(void)
243 asm volatile("sync; isync");
246 static inline void store_inst(void *p)
248 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
251 static inline void cflush(void *p)
253 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
256 static inline void cinval(void *p)
258 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
262 * Disable surveillance (the service processor watchdog function)
263 * while we are in xmon.
264 * XXX we should re-enable it when we leave. :)
266 #define SURVEILLANCE_TOKEN 9000
268 static inline void disable_surveillance(void)
270 #ifdef CONFIG_PPC_PSERIES
271 /* Since this can't be a module, args should end up below 4GB. */
272 static struct rtas_args args;
275 * At this point we have got all the cpus we can into
276 * xmon, so there is hopefully no other cpu calling RTAS
277 * at the moment, even though we don't take rtas.lock.
278 * If we did try to take rtas.lock there would be a
279 * real possibility of deadlock.
281 args.token = rtas_token("set-indicator");
282 if (args.token == RTAS_UNKNOWN_SERVICE)
286 args.rets = &args.args[3];
287 args.args[0] = SURVEILLANCE_TOKEN;
290 enter_rtas(__pa(&args));
291 #endif /* CONFIG_PPC_PSERIES */
295 static int xmon_speaker;
297 static void get_output_lock(void)
299 int me = smp_processor_id() + 0x100;
300 int last_speaker = 0, prev;
303 if (xmon_speaker == me)
306 if (xmon_speaker == 0) {
307 last_speaker = cmpxchg(&xmon_speaker, 0, me);
308 if (last_speaker == 0)
312 while (xmon_speaker == last_speaker) {
315 /* hostile takeover */
316 prev = cmpxchg(&xmon_speaker, last_speaker, me);
317 if (prev == last_speaker)
324 static void release_output_lock(void)
330 static int xmon_core(struct pt_regs *regs, int fromipi)
334 long recurse_jmp[JMP_BUF_LEN];
335 unsigned long offset;
340 unsigned long timeout;
343 local_irq_save(flags);
345 bp = in_breakpoint_table(regs->nip, &offset);
347 regs->nip = bp->address + offset;
348 atomic_dec(&bp->ref_count);
354 cpu = smp_processor_id();
355 if (cpu_isset(cpu, cpus_in_xmon)) {
358 printf("cpu 0x%x: Exception %lx %s in xmon, "
359 "returning to main loop\n",
360 cpu, regs->trap, getvecname(TRAP(regs)));
361 release_output_lock();
362 longjmp(xmon_fault_jmp[cpu], 1);
365 if (setjmp(recurse_jmp) != 0) {
366 if (!in_xmon || !xmon_gate) {
368 printf("xmon: WARNING: bad recursive fault "
369 "on cpu 0x%x\n", cpu);
370 release_output_lock();
373 secondary = !(xmon_taken && cpu == xmon_owner);
377 xmon_fault_jmp[cpu] = recurse_jmp;
378 cpu_set(cpu, cpus_in_xmon);
381 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
382 bp = at_breakpoint(regs->nip);
383 if (bp || (regs->msr & MSR_RI) == 0)
390 printf("cpu 0x%x stopped at breakpoint 0x%x (",
392 xmon_print_symbol(regs->nip, " ", ")\n");
394 if ((regs->msr & MSR_RI) == 0)
395 printf("WARNING: exception is not recoverable, "
397 release_output_lock();
402 while (secondary && !xmon_gate) {
406 secondary = test_and_set_bit(0, &in_xmon);
411 if (!secondary && !xmon_gate) {
412 /* we are the first cpu to come in */
413 /* interrupt other cpu(s) */
414 int ncpus = num_online_cpus();
419 smp_send_debugger_break(MSG_ALL_BUT_SELF);
420 /* wait for other cpus to come in */
421 for (timeout = 100000000; timeout != 0; --timeout) {
422 if (cpus_weight(cpus_in_xmon) >= ncpus)
428 disable_surveillance();
429 /* for breakpoint or single step, print the current instr. */
430 if (bp || TRAP(regs) == 0xd00)
431 ppc_inst_dump(regs->nip, 1, 0);
432 printf("enter ? for help\n");
441 if (cpu == xmon_owner) {
442 if (!test_and_set_bit(0, &xmon_taken)) {
447 while (cpu == xmon_owner)
461 /* have switched to some other cpu */
466 cpu_clear(cpu, cpus_in_xmon);
467 xmon_fault_jmp[cpu] = NULL;
469 /* UP is simple... */
471 printf("Exception %lx %s in xmon, returning to main loop\n",
472 regs->trap, getvecname(TRAP(regs)));
473 longjmp(xmon_fault_jmp[0], 1);
475 if (setjmp(recurse_jmp) == 0) {
476 xmon_fault_jmp[0] = recurse_jmp;
480 bp = at_breakpoint(regs->nip);
482 printf("Stopped at breakpoint %x (", BP_NUM(bp));
483 xmon_print_symbol(regs->nip, " ", ")\n");
485 if ((regs->msr & MSR_RI) == 0)
486 printf("WARNING: exception is not recoverable, "
489 disable_surveillance();
490 /* for breakpoint or single step, print the current instr. */
491 if (bp || TRAP(regs) == 0xd00)
492 ppc_inst_dump(regs->nip, 1, 0);
493 printf("enter ? for help\n");
502 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
503 bp = at_breakpoint(regs->nip);
505 int stepped = emulate_step(regs, bp->instr[0]);
507 regs->nip = (unsigned long) &bp->instr[0];
508 atomic_inc(&bp->ref_count);
509 } else if (stepped < 0) {
510 printf("Couldn't single-step %s instruction\n",
511 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
518 local_irq_restore(flags);
520 return cmd != 'X' && cmd != EOF;
523 int xmon(struct pt_regs *excp)
528 xmon_save_regs(®s);
532 return xmon_core(excp, 0);
536 irqreturn_t xmon_irq(int irq, void *d)
539 local_irq_save(flags);
540 printf("Keyboard interrupt\n");
541 xmon(get_irq_regs());
542 local_irq_restore(flags);
546 static int xmon_bpt(struct pt_regs *regs)
549 unsigned long offset;
551 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
554 /* Are we at the trap at bp->instr[1] for some bp? */
555 bp = in_breakpoint_table(regs->nip, &offset);
556 if (bp != NULL && offset == 4) {
557 regs->nip = bp->address + 4;
558 atomic_dec(&bp->ref_count);
562 /* Are we at a breakpoint? */
563 bp = at_breakpoint(regs->nip);
572 static int xmon_sstep(struct pt_regs *regs)
580 static int xmon_dabr_match(struct pt_regs *regs)
582 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
584 if (dabr.enabled == 0)
590 static int xmon_iabr_match(struct pt_regs *regs)
592 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
600 static int xmon_ipi(struct pt_regs *regs)
603 if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
609 static int xmon_fault_handler(struct pt_regs *regs)
612 unsigned long offset;
614 if (in_xmon && catch_memory_errors)
615 handle_fault(regs); /* doesn't return */
617 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
618 bp = in_breakpoint_table(regs->nip, &offset);
620 regs->nip = bp->address + offset;
621 atomic_dec(&bp->ref_count);
628 static struct bpt *at_breakpoint(unsigned long pc)
634 for (i = 0; i < NBPTS; ++i, ++bp)
635 if (bp->enabled && pc == bp->address)
640 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
644 off = nip - (unsigned long) bpts;
645 if (off >= sizeof(bpts))
647 off %= sizeof(struct bpt);
648 if (off != offsetof(struct bpt, instr[0])
649 && off != offsetof(struct bpt, instr[1]))
651 *offp = off - offsetof(struct bpt, instr[0]);
652 return (struct bpt *) (nip - off);
655 static struct bpt *new_breakpoint(unsigned long a)
660 bp = at_breakpoint(a);
664 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
665 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
667 bp->instr[1] = bpinstr;
668 store_inst(&bp->instr[1]);
673 printf("Sorry, no free breakpoints. Please clear one first.\n");
677 static void insert_bpts(void)
683 for (i = 0; i < NBPTS; ++i, ++bp) {
684 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
686 if (mread(bp->address, &bp->instr[0], 4) != 4) {
687 printf("Couldn't read instruction at %lx, "
688 "disabling breakpoint there\n", bp->address);
692 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
693 printf("Breakpoint at %lx is on an mtmsrd or rfid "
694 "instruction, disabling it\n", bp->address);
698 store_inst(&bp->instr[0]);
699 if (bp->enabled & BP_IABR)
701 if (mwrite(bp->address, &bpinstr, 4) != 4) {
702 printf("Couldn't write instruction at %lx, "
703 "disabling breakpoint there\n", bp->address);
704 bp->enabled &= ~BP_TRAP;
707 store_inst((void *)bp->address);
711 static void insert_cpu_bpts(void)
714 set_dabr(dabr.address | (dabr.enabled & 7));
715 if (iabr && cpu_has_feature(CPU_FTR_IABR))
716 mtspr(SPRN_IABR, iabr->address
717 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
720 static void remove_bpts(void)
727 for (i = 0; i < NBPTS; ++i, ++bp) {
728 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
730 if (mread(bp->address, &instr, 4) == 4
732 && mwrite(bp->address, &bp->instr, 4) != 4)
733 printf("Couldn't remove breakpoint at %lx\n",
736 store_inst((void *)bp->address);
740 static void remove_cpu_bpts(void)
743 if (cpu_has_feature(CPU_FTR_IABR))
747 /* Command interpreting routine */
748 static char *last_cmd;
751 cmds(struct pt_regs *excp)
758 if (!xmon_no_auto_backtrace) {
759 xmon_no_auto_backtrace = 1;
760 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
765 printf("%x:", smp_processor_id());
766 #endif /* CONFIG_SMP */
772 if (last_cmd == NULL)
774 take_input(last_cmd);
808 prregs(excp); /* print regs */
823 if (do_spu_cmd() == 0)
832 printf(" <no input ...>\n");
854 #ifdef CONFIG_PPC_STD_MMU
860 printf("Unrecognized command: ");
862 if (' ' < cmd && cmd <= '~')
865 printf("\\x%x", cmd);
867 } while (cmd != '\n');
868 printf(" (type ? for help)\n");
875 * Step a single instruction.
876 * Some instructions we emulate, others we execute with MSR_SE set.
878 static int do_step(struct pt_regs *regs)
883 /* check we are in 64-bit kernel mode, translation enabled */
884 if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
885 if (mread(regs->nip, &instr, 4) == 4) {
886 stepped = emulate_step(regs, instr);
888 printf("Couldn't single-step %s instruction\n",
889 (IS_RFID(instr)? "rfid": "mtmsrd"));
893 regs->trap = 0xd00 | (regs->trap & 1);
894 printf("stepped to ");
895 xmon_print_symbol(regs->nip, " ", "\n");
896 ppc_inst_dump(regs->nip, 1, 0);
905 static void bootcmds(void)
911 ppc_md.restart(NULL);
918 static int cpu_cmd(void)
925 if (!scanhex(&cpu)) {
926 /* print cpus waiting or in xmon */
927 printf("cpus stopped:");
929 for (cpu = 0; cpu < NR_CPUS; ++cpu) {
930 if (cpu_isset(cpu, cpus_in_xmon)) {
936 printf("-%x", cpu - 1);
941 printf("-%x", NR_CPUS - 1);
945 /* try to switch to cpu specified */
946 if (!cpu_isset(cpu, cpus_in_xmon)) {
947 printf("cpu 0x%x isn't in xmon\n", cpu);
954 while (!xmon_taken) {
955 if (--timeout == 0) {
956 if (test_and_set_bit(0, &xmon_taken))
958 /* take control back */
960 xmon_owner = smp_processor_id();
961 printf("cpu %u didn't take control\n", cpu);
969 #endif /* CONFIG_SMP */
972 static unsigned short fcstab[256] = {
973 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
974 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
975 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
976 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
977 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
978 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
979 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
980 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
981 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
982 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
983 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
984 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
985 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
986 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
987 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
988 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
989 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
990 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
991 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
992 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
993 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
994 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
995 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
996 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
997 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
998 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
999 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1000 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1001 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1002 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1003 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1004 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1007 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1016 if (!scanhex(&adrs))
1018 if (!scanhex(&ncsum))
1021 for (i = 0; i < ncsum; ++i) {
1022 if (mread(adrs+i, &v, 1) == 0) {
1023 printf("csum stopped at %x\n", adrs+i);
1028 printf("%x\n", fcs);
1032 * Check if this is a suitable place to put a breakpoint.
1034 static long check_bp_loc(unsigned long addr)
1039 if (!is_kernel_addr(addr)) {
1040 printf("Breakpoints may only be placed at kernel addresses\n");
1043 if (!mread(addr, &instr, sizeof(instr))) {
1044 printf("Can't read instruction at address %lx\n", addr);
1047 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1048 printf("Breakpoints may not be placed on mtmsrd or rfid "
1055 static char *breakpoint_help_string =
1056 "Breakpoint command usage:\n"
1057 "b show breakpoints\n"
1058 "b <addr> [cnt] set breakpoint at given instr addr\n"
1059 "bc clear all breakpoints\n"
1060 "bc <n/addr> clear breakpoint number n or at addr\n"
1061 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1062 "bd <addr> [cnt] set hardware data breakpoint\n"
1072 const char badaddr[] = "Only kernel addresses are permitted "
1073 "for breakpoints\n";
1078 case 'd': /* bd - hardware data breakpoint */
1083 else if (cmd == 'w')
1089 if (scanhex(&dabr.address)) {
1090 if (!is_kernel_addr(dabr.address)) {
1095 dabr.enabled = mode | BP_DABR;
1099 case 'i': /* bi - hardware instr breakpoint */
1100 if (!cpu_has_feature(CPU_FTR_IABR)) {
1101 printf("Hardware instruction breakpoint "
1102 "not supported on this cpu\n");
1106 iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1111 if (!check_bp_loc(a))
1113 bp = new_breakpoint(a);
1115 bp->enabled |= BP_IABR | BP_IABR_TE;
1123 /* clear all breakpoints */
1124 for (i = 0; i < NBPTS; ++i)
1125 bpts[i].enabled = 0;
1128 printf("All breakpoints cleared\n");
1132 if (a <= NBPTS && a >= 1) {
1133 /* assume a breakpoint number */
1134 bp = &bpts[a-1]; /* bp nums are 1 based */
1136 /* assume a breakpoint address */
1137 bp = at_breakpoint(a);
1139 printf("No breakpoint at %x\n", a);
1144 printf("Cleared breakpoint %x (", BP_NUM(bp));
1145 xmon_print_symbol(bp->address, " ", ")\n");
1153 printf(breakpoint_help_string);
1158 /* print all breakpoints */
1159 printf(" type address\n");
1161 printf(" data "REG" [", dabr.address);
1162 if (dabr.enabled & 1)
1164 if (dabr.enabled & 2)
1168 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1171 printf("%2x %s ", BP_NUM(bp),
1172 (bp->enabled & BP_IABR)? "inst": "trap");
1173 xmon_print_symbol(bp->address, " ", "\n");
1178 if (!check_bp_loc(a))
1180 bp = new_breakpoint(a);
1182 bp->enabled |= BP_TRAP;
1187 /* Very cheap human name for vector lookup. */
1189 const char *getvecname(unsigned long vec)
1194 case 0x100: ret = "(System Reset)"; break;
1195 case 0x200: ret = "(Machine Check)"; break;
1196 case 0x300: ret = "(Data Access)"; break;
1197 case 0x380: ret = "(Data SLB Access)"; break;
1198 case 0x400: ret = "(Instruction Access)"; break;
1199 case 0x480: ret = "(Instruction SLB Access)"; break;
1200 case 0x500: ret = "(Hardware Interrupt)"; break;
1201 case 0x600: ret = "(Alignment)"; break;
1202 case 0x700: ret = "(Program Check)"; break;
1203 case 0x800: ret = "(FPU Unavailable)"; break;
1204 case 0x900: ret = "(Decrementer)"; break;
1205 case 0xc00: ret = "(System Call)"; break;
1206 case 0xd00: ret = "(Single Step)"; break;
1207 case 0xf00: ret = "(Performance Monitor)"; break;
1208 case 0xf20: ret = "(Altivec Unavailable)"; break;
1209 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1215 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1216 unsigned long *endp)
1218 unsigned long size, offset;
1222 *startp = *endp = 0;
1225 if (setjmp(bus_error_jmp) == 0) {
1226 catch_memory_errors = 1;
1228 name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr);
1230 *startp = pc - offset;
1231 *endp = pc - offset + size;
1235 catch_memory_errors = 0;
1238 static int xmon_depth_to_print = 64;
1241 #define LRSAVE_OFFSET 0x10
1242 #define REG_FRAME_MARKER 0x7265677368657265ul /* "regshere" */
1243 #define MARKER_OFFSET 0x60
1244 #define REGS_OFFSET 0x70
1246 #define LRSAVE_OFFSET 4
1247 #define REG_FRAME_MARKER 0x72656773
1248 #define MARKER_OFFSET 8
1249 #define REGS_OFFSET 16
1252 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1256 unsigned long newsp;
1257 unsigned long marker;
1259 struct pt_regs regs;
1262 if (sp < PAGE_OFFSET) {
1264 printf("SP (%lx) is in userspace\n", sp);
1268 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1269 || !mread(sp, &newsp, sizeof(unsigned long))) {
1270 printf("Couldn't read stack frame at %lx\n", sp);
1275 * For the first stack frame, try to work out if
1276 * LR and/or the saved LR value in the bottommost
1277 * stack frame are valid.
1279 if ((pc | lr) != 0) {
1280 unsigned long fnstart, fnend;
1281 unsigned long nextip;
1284 get_function_bounds(pc, &fnstart, &fnend);
1287 mread(newsp + LRSAVE_OFFSET, &nextip,
1288 sizeof(unsigned long));
1290 if (lr < PAGE_OFFSET
1291 || (fnstart <= lr && lr < fnend))
1293 } else if (lr == nextip) {
1295 } else if (lr >= PAGE_OFFSET
1296 && !(fnstart <= lr && lr < fnend)) {
1297 printf("[link register ] ");
1298 xmon_print_symbol(lr, " ", "\n");
1301 printf("["REG"] ", sp);
1302 xmon_print_symbol(ip, " ", " (unreliable)\n");
1307 printf("["REG"] ", sp);
1308 xmon_print_symbol(ip, " ", "\n");
1311 /* Look for "regshere" marker to see if this is
1312 an exception frame. */
1313 if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1314 && marker == REG_FRAME_MARKER) {
1315 if (mread(sp + REGS_OFFSET, ®s, sizeof(regs))
1317 printf("Couldn't read registers at %lx\n",
1321 printf("--- Exception: %lx %s at ", regs.trap,
1322 getvecname(TRAP(®s)));
1325 xmon_print_symbol(pc, " ", "\n");
1332 } while (count++ < xmon_depth_to_print);
1335 static void backtrace(struct pt_regs *excp)
1340 xmon_show_stack(sp, 0, 0);
1342 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1346 static void print_bug_trap(struct pt_regs *regs)
1348 const struct bug_entry *bug;
1351 if (regs->msr & MSR_PR)
1352 return; /* not in kernel */
1353 addr = regs->nip; /* address of trap instruction */
1354 if (addr < PAGE_OFFSET)
1356 bug = find_bug(regs->nip);
1359 if (is_warning_bug(bug))
1362 #ifdef CONFIG_DEBUG_BUGVERBOSE
1363 printf("kernel BUG at %s:%u!\n",
1364 bug->file, bug->line);
1366 printf("kernel BUG at %p!\n", (void *)bug->bug_addr);
1370 void excprint(struct pt_regs *fp)
1375 printf("cpu 0x%x: ", smp_processor_id());
1376 #endif /* CONFIG_SMP */
1379 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1381 xmon_print_symbol(fp->nip, ": ", "\n");
1383 printf(" lr: ", fp->link);
1384 xmon_print_symbol(fp->link, ": ", "\n");
1386 printf(" sp: %lx\n", fp->gpr[1]);
1387 printf(" msr: %lx\n", fp->msr);
1389 if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1390 printf(" dar: %lx\n", fp->dar);
1392 printf(" dsisr: %lx\n", fp->dsisr);
1395 printf(" current = 0x%lx\n", current);
1397 printf(" paca = 0x%lx\n", get_paca());
1400 printf(" pid = %ld, comm = %s\n",
1401 current->pid, current->comm);
1408 void prregs(struct pt_regs *fp)
1412 struct pt_regs regs;
1414 if (scanhex(&base)) {
1415 if (setjmp(bus_error_jmp) == 0) {
1416 catch_memory_errors = 1;
1418 regs = *(struct pt_regs *)base;
1422 catch_memory_errors = 0;
1423 printf("*** Error reading registers from "REG"\n",
1427 catch_memory_errors = 0;
1432 if (FULL_REGS(fp)) {
1433 for (n = 0; n < 16; ++n)
1434 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1435 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1437 for (n = 0; n < 7; ++n)
1438 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1439 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1442 for (n = 0; n < 32; ++n) {
1443 printf("R%.2d = %.8x%s", n, fp->gpr[n],
1444 (n & 3) == 3? "\n": " ");
1445 if (n == 12 && !FULL_REGS(fp)) {
1452 xmon_print_symbol(fp->nip, " ", "\n");
1454 xmon_print_symbol(fp->link, " ", "\n");
1455 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
1456 printf("ctr = "REG" xer = "REG" trap = %4lx\n",
1457 fp->ctr, fp->xer, fp->trap);
1459 if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1460 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1463 void cacheflush(void)
1466 unsigned long nflush;
1471 scanhex((void *)&adrs);
1476 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1477 if (setjmp(bus_error_jmp) == 0) {
1478 catch_memory_errors = 1;
1482 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1483 cflush((void *) adrs);
1485 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1486 cinval((void *) adrs);
1489 /* wait a little while to see if we get a machine check */
1492 catch_memory_errors = 0;
1498 unsigned int instrs[2];
1499 unsigned long (*code)(void);
1500 unsigned long ret = -1UL;
1502 unsigned long opd[3];
1504 opd[0] = (unsigned long)instrs;
1507 code = (unsigned long (*)(void)) opd;
1509 code = (unsigned long (*)(void)) instrs;
1512 /* mfspr r3,n; blr */
1513 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1514 instrs[1] = 0x4e800020;
1516 store_inst(instrs+1);
1518 if (setjmp(bus_error_jmp) == 0) {
1519 catch_memory_errors = 1;
1525 /* wait a little while to see if we get a machine check */
1534 write_spr(int n, unsigned long val)
1536 unsigned int instrs[2];
1537 unsigned long (*code)(unsigned long);
1539 unsigned long opd[3];
1541 opd[0] = (unsigned long)instrs;
1544 code = (unsigned long (*)(unsigned long)) opd;
1546 code = (unsigned long (*)(unsigned long)) instrs;
1549 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1550 instrs[1] = 0x4e800020;
1552 store_inst(instrs+1);
1554 if (setjmp(bus_error_jmp) == 0) {
1555 catch_memory_errors = 1;
1561 /* wait a little while to see if we get a machine check */
1567 static unsigned long regno;
1568 extern char exc_prolog;
1569 extern char dec_exc;
1571 void super_regs(void)
1578 unsigned long sp, toc;
1579 asm("mr %0,1" : "=r" (sp) :);
1580 asm("mr %0,2" : "=r" (toc) :);
1582 printf("msr = "REG" sprg0= "REG"\n",
1583 mfmsr(), mfspr(SPRN_SPRG0));
1584 printf("pvr = "REG" sprg1= "REG"\n",
1585 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
1586 printf("dec = "REG" sprg2= "REG"\n",
1587 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1588 printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1589 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
1590 #ifdef CONFIG_PPC_ISERIES
1591 if (firmware_has_feature(FW_FEATURE_ISERIES)) {
1592 struct paca_struct *ptrPaca;
1593 struct lppaca *ptrLpPaca;
1594 struct ItLpRegSave *ptrLpRegSave;
1596 /* Dump out relevant Paca data areas. */
1598 ptrPaca = get_paca();
1600 printf(" Local Processor Control Area (LpPaca): \n");
1601 ptrLpPaca = ptrPaca->lppaca_ptr;
1602 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1603 ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
1604 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1605 ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
1606 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
1608 printf(" Local Processor Register Save Area (LpRegSave): \n");
1609 ptrLpRegSave = ptrPaca->reg_save_ptr;
1610 printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n",
1611 ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
1612 printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n",
1613 ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
1614 printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n",
1615 ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
1625 val = read_spr(regno);
1627 write_spr(regno, val);
1630 printf("spr %lx = %lx\n", regno, read_spr(regno));
1637 * Stuff for reading and writing memory safely
1640 mread(unsigned long adrs, void *buf, int size)
1646 if (setjmp(bus_error_jmp) == 0) {
1647 catch_memory_errors = 1;
1653 *(u16 *)q = *(u16 *)p;
1656 *(u32 *)q = *(u32 *)p;
1659 *(u64 *)q = *(u64 *)p;
1662 for( ; n < size; ++n) {
1668 /* wait a little while to see if we get a machine check */
1672 catch_memory_errors = 0;
1677 mwrite(unsigned long adrs, void *buf, int size)
1683 if (setjmp(bus_error_jmp) == 0) {
1684 catch_memory_errors = 1;
1690 *(u16 *)p = *(u16 *)q;
1693 *(u32 *)p = *(u32 *)q;
1696 *(u64 *)p = *(u64 *)q;
1699 for ( ; n < size; ++n) {
1705 /* wait a little while to see if we get a machine check */
1709 printf("*** Error writing address %x\n", adrs + n);
1711 catch_memory_errors = 0;
1715 static int fault_type;
1716 static int fault_except;
1717 static char *fault_chars[] = { "--", "**", "##" };
1719 static int handle_fault(struct pt_regs *regs)
1721 fault_except = TRAP(regs);
1722 switch (TRAP(regs)) {
1734 longjmp(bus_error_jmp, 1);
1739 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1742 byterev(unsigned char *val, int size)
1748 SWAP(val[0], val[1], t);
1751 SWAP(val[0], val[3], t);
1752 SWAP(val[1], val[2], t);
1754 case 8: /* is there really any use for this? */
1755 SWAP(val[0], val[7], t);
1756 SWAP(val[1], val[6], t);
1757 SWAP(val[2], val[5], t);
1758 SWAP(val[3], val[4], t);
1766 static char *memex_help_string =
1767 "Memory examine command usage:\n"
1768 "m [addr] [flags] examine/change memory\n"
1769 " addr is optional. will start where left off.\n"
1770 " flags may include chars from this set:\n"
1771 " b modify by bytes (default)\n"
1772 " w modify by words (2 byte)\n"
1773 " l modify by longs (4 byte)\n"
1774 " d modify by doubleword (8 byte)\n"
1775 " r toggle reverse byte order mode\n"
1776 " n do not read memory (for i/o spaces)\n"
1777 " . ok to read (default)\n"
1778 "NOTE: flags are saved as defaults\n"
1781 static char *memex_subcmd_help_string =
1782 "Memory examine subcommands:\n"
1783 " hexval write this val to current location\n"
1784 " 'string' write chars from string to this location\n"
1785 " ' increment address\n"
1786 " ^ decrement address\n"
1787 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1788 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1789 " ` clear no-read flag\n"
1790 " ; stay at this addr\n"
1791 " v change to byte mode\n"
1792 " w change to word (2 byte) mode\n"
1793 " l change to long (4 byte) mode\n"
1794 " u change to doubleword (8 byte) mode\n"
1795 " m addr change current addr\n"
1796 " n toggle no-read flag\n"
1797 " r toggle byte reverse flag\n"
1798 " < count back up count bytes\n"
1799 " > count skip forward count bytes\n"
1800 " x exit this mode\n"
1806 int cmd, inc, i, nslash;
1808 unsigned char val[16];
1810 scanhex((void *)&adrs);
1813 printf(memex_help_string);
1819 while ((cmd = skipbl()) != '\n') {
1821 case 'b': size = 1; break;
1822 case 'w': size = 2; break;
1823 case 'l': size = 4; break;
1824 case 'd': size = 8; break;
1825 case 'r': brev = !brev; break;
1826 case 'n': mnoread = 1; break;
1827 case '.': mnoread = 0; break;
1836 n = mread(adrs, val, size);
1837 printf(REG"%c", adrs, brev? 'r': ' ');
1842 for (i = 0; i < n; ++i)
1843 printf("%.2x", val[i]);
1844 for (; i < size; ++i)
1845 printf("%s", fault_chars[fault_type]);
1852 for (i = 0; i < size; ++i)
1853 val[i] = n >> (i * 8);
1856 mwrite(adrs, val, size);
1869 else if( n == '\'' )
1871 for (i = 0; i < size; ++i)
1872 val[i] = n >> (i * 8);
1875 mwrite(adrs, val, size);
1912 adrs -= 1 << nslash;
1916 adrs += 1 << nslash;
1920 adrs += 1 << -nslash;
1924 adrs -= 1 << -nslash;
1927 scanhex((void *)&adrs);
1946 printf(memex_subcmd_help_string);
1961 case 'n': c = '\n'; break;
1962 case 'r': c = '\r'; break;
1963 case 'b': c = '\b'; break;
1964 case 't': c = '\t'; break;
1969 static void xmon_rawdump (unsigned long adrs, long ndump)
1972 unsigned char temp[16];
1974 for (n = ndump; n > 0;) {
1976 nr = mread(adrs, temp, r);
1978 for (m = 0; m < r; ++m) {
1980 printf("%.2x", temp[m]);
1982 printf("%s", fault_chars[fault_type]);
1991 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
1992 || ('a' <= (c) && (c) <= 'f') \
1993 || ('A' <= (c) && (c) <= 'F'))
2000 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
2002 scanhex((void *)&adrs);
2009 else if (nidump > MAX_DUMP)
2011 adrs += ppc_inst_dump(adrs, nidump, 1);
2013 } else if (c == 'r') {
2017 xmon_rawdump(adrs, ndump);
2024 else if (ndump > MAX_DUMP)
2026 prdump(adrs, ndump);
2033 prdump(unsigned long adrs, long ndump)
2035 long n, m, c, r, nr;
2036 unsigned char temp[16];
2038 for (n = ndump; n > 0;) {
2042 nr = mread(adrs, temp, r);
2044 for (m = 0; m < r; ++m) {
2045 if ((m & (sizeof(long) - 1)) == 0 && m > 0)
2048 printf("%.2x", temp[m]);
2050 printf("%s", fault_chars[fault_type]);
2052 for (; m < 16; ++m) {
2053 if ((m & (sizeof(long) - 1)) == 0)
2058 for (m = 0; m < r; ++m) {
2061 putchar(' ' <= c && c <= '~'? c: '.');
2074 typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr);
2077 generic_inst_dump(unsigned long adr, long count, int praddr,
2078 instruction_dump_func dump_func)
2081 unsigned long first_adr;
2082 unsigned long inst, last_inst = 0;
2083 unsigned char val[4];
2086 for (first_adr = adr; count > 0; --count, adr += 4) {
2087 nr = mread(adr, val, 4);
2090 const char *x = fault_chars[fault_type];
2091 printf(REG" %s%s%s%s\n", adr, x, x, x, x);
2095 inst = GETWORD(val);
2096 if (adr > first_adr && inst == last_inst) {
2106 printf(REG" %.8x", adr, inst);
2108 dump_func(inst, adr);
2111 return adr - first_adr;
2115 ppc_inst_dump(unsigned long adr, long count, int praddr)
2117 return generic_inst_dump(adr, count, praddr, print_insn_powerpc);
2121 print_address(unsigned long addr)
2123 xmon_print_symbol(addr, "\t# ", "");
2128 * Memory operations - move, set, print differences
2130 static unsigned long mdest; /* destination address */
2131 static unsigned long msrc; /* source address */
2132 static unsigned long mval; /* byte value to set memory to */
2133 static unsigned long mcount; /* # bytes to affect */
2134 static unsigned long mdiffs; /* max # differences to print */
2139 scanhex((void *)&mdest);
2140 if( termch != '\n' )
2142 scanhex((void *)(cmd == 's'? &mval: &msrc));
2143 if( termch != '\n' )
2145 scanhex((void *)&mcount);
2148 memmove((void *)mdest, (void *)msrc, mcount);
2151 memset((void *)mdest, mval, mcount);
2154 if( termch != '\n' )
2156 scanhex((void *)&mdiffs);
2157 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2163 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2168 for( n = nb; n > 0; --n )
2169 if( *p1++ != *p2++ )
2170 if( ++prt <= maxpr )
2171 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2172 p1[-1], p2 - 1, p2[-1]);
2174 printf("Total of %d differences\n", prt);
2177 static unsigned mend;
2178 static unsigned mask;
2184 unsigned char val[4];
2187 scanhex((void *)&mdest);
2188 if (termch != '\n') {
2190 scanhex((void *)&mend);
2191 if (termch != '\n') {
2193 scanhex((void *)&mval);
2195 if (termch != '\n') termch = 0;
2196 scanhex((void *)&mask);
2200 for (a = mdest; a < mend; a += 4) {
2201 if (mread(a, val, 4) == 4
2202 && ((GETWORD(val) ^ mval) & mask) == 0) {
2203 printf("%.16x: %.16x\n", a, GETWORD(val));
2210 static unsigned long mskip = 0x1000;
2211 static unsigned long mlim = 0xffffffff;
2221 if (termch != '\n') termch = 0;
2223 if (termch != '\n') termch = 0;
2226 for (a = mdest; a < mlim; a += mskip) {
2227 ok = mread(a, &v, 1);
2229 printf("%.8x .. ", a);
2230 } else if (!ok && ook)
2231 printf("%.8x\n", a - mskip);
2237 printf("%.8x\n", a - mskip);
2242 unsigned long args[8];
2245 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2246 unsigned long, unsigned long, unsigned long,
2247 unsigned long, unsigned long, unsigned long);
2250 if (!scanhex(&adrs))
2254 for (i = 0; i < 8; ++i)
2256 for (i = 0; i < 8; ++i) {
2257 if (!scanhex(&args[i]) || termch == '\n')
2261 func = (callfunc_t) adrs;
2263 if (setjmp(bus_error_jmp) == 0) {
2264 catch_memory_errors = 1;
2266 ret = func(args[0], args[1], args[2], args[3],
2267 args[4], args[5], args[6], args[7]);
2269 printf("return value is %x\n", ret);
2271 printf("*** %x exception occurred\n", fault_except);
2273 catch_memory_errors = 0;
2276 /* Input scanning routines */
2287 while( c == ' ' || c == '\t' )
2293 static char *regnames[N_PTREGS] = {
2294 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2295 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2296 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2297 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2298 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2304 "trap", "dar", "dsisr", "res"
2308 scanhex(unsigned long *vp)
2315 /* parse register name */
2319 for (i = 0; i < sizeof(regname) - 1; ++i) {
2328 for (i = 0; i < N_PTREGS; ++i) {
2329 if (strcmp(regnames[i], regname) == 0) {
2330 if (xmon_regs == NULL) {
2331 printf("regs not available\n");
2334 *vp = ((unsigned long *)xmon_regs)[i];
2338 printf("invalid register name '%%%s'\n", regname);
2342 /* skip leading "0x" if any */
2356 } else if (c == '$') {
2358 for (i=0; i<63; i++) {
2368 if (setjmp(bus_error_jmp) == 0) {
2369 catch_memory_errors = 1;
2371 *vp = kallsyms_lookup_name(tmpstr);
2374 catch_memory_errors = 0;
2376 printf("unknown symbol '%s'\n", tmpstr);
2411 if( '0' <= c && c <= '9' )
2413 if( 'A' <= c && c <= 'F' )
2414 return c - ('A' - 10);
2415 if( 'a' <= c && c <= 'f' )
2416 return c - ('a' - 10);
2421 getstring(char *s, int size)
2432 } while( c != ' ' && c != '\t' && c != '\n' );
2437 static char line[256];
2438 static char *lineptr;
2449 if (lineptr == NULL || *lineptr == 0) {
2450 if (xmon_gets(line, sizeof(line)) == NULL) {
2460 take_input(char *str)
2469 int type = inchar();
2471 static char tmp[64];
2476 xmon_print_symbol(addr, ": ", "\n");
2481 if (setjmp(bus_error_jmp) == 0) {
2482 catch_memory_errors = 1;
2484 addr = kallsyms_lookup_name(tmp);
2486 printf("%s: %lx\n", tmp, addr);
2488 printf("Symbol '%s' not found.\n", tmp);
2491 catch_memory_errors = 0;
2498 /* Print an address in numeric and symbolic form (if possible) */
2499 static void xmon_print_symbol(unsigned long address, const char *mid,
2503 const char *name = NULL;
2504 unsigned long offset, size;
2506 printf(REG, address);
2507 if (setjmp(bus_error_jmp) == 0) {
2508 catch_memory_errors = 1;
2510 name = kallsyms_lookup(address, &size, &offset, &modname,
2513 /* wait a little while to see if we get a machine check */
2517 catch_memory_errors = 0;
2520 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2522 printf(" [%s]", modname);
2524 printf("%s", after);
2528 static void dump_slb(void)
2533 printf("SLB contents of cpu %x\n", smp_processor_id());
2535 for (i = 0; i < SLB_NUM_ENTRIES; i++) {
2536 asm volatile("slbmfee %0,%1" : "=r" (tmp) : "r" (i));
2537 printf("%02d %016lx ", i, tmp);
2539 asm volatile("slbmfev %0,%1" : "=r" (tmp) : "r" (i));
2540 printf("%016lx\n", tmp);
2544 static void dump_stab(void)
2547 unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2549 printf("Segment table contents of cpu %x\n", smp_processor_id());
2551 for (i = 0; i < PAGE_SIZE/16; i++) {
2558 printf("%03d %016lx ", i, a);
2559 printf("%016lx\n", b);
2564 void dump_segments(void)
2566 if (cpu_has_feature(CPU_FTR_SLB))
2573 #ifdef CONFIG_PPC_STD_MMU_32
2574 void dump_segments(void)
2579 for (i = 0; i < 16; ++i)
2580 printf(" %x", mfsrin(i));
2585 void xmon_init(int enable)
2587 #ifdef CONFIG_PPC_ISERIES
2588 if (firmware_has_feature(FW_FEATURE_ISERIES))
2593 __debugger_ipi = xmon_ipi;
2594 __debugger_bpt = xmon_bpt;
2595 __debugger_sstep = xmon_sstep;
2596 __debugger_iabr_match = xmon_iabr_match;
2597 __debugger_dabr_match = xmon_dabr_match;
2598 __debugger_fault_handler = xmon_fault_handler;
2601 __debugger_ipi = NULL;
2602 __debugger_bpt = NULL;
2603 __debugger_sstep = NULL;
2604 __debugger_iabr_match = NULL;
2605 __debugger_dabr_match = NULL;
2606 __debugger_fault_handler = NULL;
2611 #ifdef CONFIG_MAGIC_SYSRQ
2612 static void sysrq_handle_xmon(int key, struct tty_struct *tty)
2614 /* ensure xmon is enabled */
2616 debugger(get_irq_regs());
2619 static struct sysrq_key_op sysrq_xmon_op =
2621 .handler = sysrq_handle_xmon,
2623 .action_msg = "Entering xmon",
2626 static int __init setup_xmon_sysrq(void)
2628 #ifdef CONFIG_PPC_ISERIES
2629 if (firmware_has_feature(FW_FEATURE_ISERIES))
2632 register_sysrq_key('x', &sysrq_xmon_op);
2635 __initcall(setup_xmon_sysrq);
2636 #endif /* CONFIG_MAGIC_SYSRQ */
2638 int __initdata xmon_early, xmon_off;
2640 static int __init early_parse_xmon(char *p)
2642 if (!p || strncmp(p, "early", 5) == 0) {
2643 /* just "xmon" is equivalent to "xmon=early" */
2646 } else if (strncmp(p, "on", 2) == 0)
2648 else if (strncmp(p, "off", 3) == 0)
2650 else if (strncmp(p, "nobt", 4) == 0)
2651 xmon_no_auto_backtrace = 1;
2657 early_param("xmon", early_parse_xmon);
2659 void __init xmon_setup(void)
2661 #ifdef CONFIG_XMON_DEFAULT
2669 #ifdef CONFIG_SPU_BASE
2673 u64 saved_mfc_sr1_RW;
2674 u32 saved_spu_runcntl_RW;
2675 unsigned long dump_addr;
2679 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
2681 static struct spu_info spu_info[XMON_NUM_SPUS];
2683 void xmon_register_spus(struct list_head *list)
2687 list_for_each_entry(spu, list, full_list) {
2688 if (spu->number >= XMON_NUM_SPUS) {
2693 spu_info[spu->number].spu = spu;
2694 spu_info[spu->number].stopped_ok = 0;
2695 spu_info[spu->number].dump_addr = (unsigned long)
2696 spu_info[spu->number].spu->local_store;
2700 static void stop_spus(void)
2706 for (i = 0; i < XMON_NUM_SPUS; i++) {
2707 if (!spu_info[i].spu)
2710 if (setjmp(bus_error_jmp) == 0) {
2711 catch_memory_errors = 1;
2714 spu = spu_info[i].spu;
2716 spu_info[i].saved_spu_runcntl_RW =
2717 in_be32(&spu->problem->spu_runcntl_RW);
2719 tmp = spu_mfc_sr1_get(spu);
2720 spu_info[i].saved_mfc_sr1_RW = tmp;
2722 tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
2723 spu_mfc_sr1_set(spu, tmp);
2728 spu_info[i].stopped_ok = 1;
2730 printf("Stopped spu %.2d (was %s)\n", i,
2731 spu_info[i].saved_spu_runcntl_RW ?
2732 "running" : "stopped");
2734 catch_memory_errors = 0;
2735 printf("*** Error stopping spu %.2d\n", i);
2737 catch_memory_errors = 0;
2741 static void restart_spus(void)
2746 for (i = 0; i < XMON_NUM_SPUS; i++) {
2747 if (!spu_info[i].spu)
2750 if (!spu_info[i].stopped_ok) {
2751 printf("*** Error, spu %d was not successfully stopped"
2752 ", not restarting\n", i);
2756 if (setjmp(bus_error_jmp) == 0) {
2757 catch_memory_errors = 1;
2760 spu = spu_info[i].spu;
2761 spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
2762 out_be32(&spu->problem->spu_runcntl_RW,
2763 spu_info[i].saved_spu_runcntl_RW);
2768 printf("Restarted spu %.2d\n", i);
2770 catch_memory_errors = 0;
2771 printf("*** Error restarting spu %.2d\n", i);
2773 catch_memory_errors = 0;
2777 #define DUMP_WIDTH 23
2778 #define DUMP_VALUE(format, field, value) \
2780 if (setjmp(bus_error_jmp) == 0) { \
2781 catch_memory_errors = 1; \
2783 printf(" %-*s = "format"\n", DUMP_WIDTH, \
2788 catch_memory_errors = 0; \
2789 printf(" %-*s = *** Error reading field.\n", \
2790 DUMP_WIDTH, #field); \
2792 catch_memory_errors = 0; \
2795 #define DUMP_FIELD(obj, format, field) \
2796 DUMP_VALUE(format, field, obj->field)
2798 static void dump_spu_fields(struct spu *spu)
2800 printf("Dumping spu fields at address %p:\n", spu);
2802 DUMP_FIELD(spu, "0x%x", number);
2803 DUMP_FIELD(spu, "%s", name);
2804 DUMP_FIELD(spu, "0x%lx", local_store_phys);
2805 DUMP_FIELD(spu, "0x%p", local_store);
2806 DUMP_FIELD(spu, "0x%lx", ls_size);
2807 DUMP_FIELD(spu, "0x%x", node);
2808 DUMP_FIELD(spu, "0x%lx", flags);
2809 DUMP_FIELD(spu, "0x%lx", dar);
2810 DUMP_FIELD(spu, "0x%lx", dsisr);
2811 DUMP_FIELD(spu, "%d", class_0_pending);
2812 DUMP_FIELD(spu, "0x%lx", irqs[0]);
2813 DUMP_FIELD(spu, "0x%lx", irqs[1]);
2814 DUMP_FIELD(spu, "0x%lx", irqs[2]);
2815 DUMP_FIELD(spu, "0x%x", slb_replace);
2816 DUMP_FIELD(spu, "%d", pid);
2817 DUMP_FIELD(spu, "0x%p", mm);
2818 DUMP_FIELD(spu, "0x%p", ctx);
2819 DUMP_FIELD(spu, "0x%p", rq);
2820 DUMP_FIELD(spu, "0x%p", timestamp);
2821 DUMP_FIELD(spu, "0x%lx", problem_phys);
2822 DUMP_FIELD(spu, "0x%p", problem);
2823 DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
2824 in_be32(&spu->problem->spu_runcntl_RW));
2825 DUMP_VALUE("0x%x", problem->spu_status_R,
2826 in_be32(&spu->problem->spu_status_R));
2827 DUMP_VALUE("0x%x", problem->spu_npc_RW,
2828 in_be32(&spu->problem->spu_npc_RW));
2829 DUMP_FIELD(spu, "0x%p", priv2);
2830 DUMP_FIELD(spu, "0x%p", pdata);
2834 spu_inst_dump(unsigned long adr, long count, int praddr)
2836 return generic_inst_dump(adr, count, praddr, print_insn_spu);
2839 static void dump_spu_ls(unsigned long num, int subcmd)
2841 unsigned long offset, addr, ls_addr;
2843 if (setjmp(bus_error_jmp) == 0) {
2844 catch_memory_errors = 1;
2846 ls_addr = (unsigned long)spu_info[num].spu->local_store;
2850 catch_memory_errors = 0;
2851 printf("*** Error: accessing spu info for spu %d\n", num);
2854 catch_memory_errors = 0;
2856 if (scanhex(&offset))
2857 addr = ls_addr + offset;
2859 addr = spu_info[num].dump_addr;
2861 if (addr >= ls_addr + LS_SIZE) {
2862 printf("*** Error: address outside of local store\n");
2868 addr += spu_inst_dump(addr, 16, 1);
2878 spu_info[num].dump_addr = addr;
2881 static int do_spu_cmd(void)
2883 static unsigned long num = 0;
2884 int cmd, subcmd = 0;
2896 if (isxdigit(subcmd) || subcmd == '\n')
2900 if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
2901 printf("*** Error: invalid spu number\n");
2907 dump_spu_fields(spu_info[num].spu);
2910 dump_spu_ls(num, subcmd);
2921 #else /* ! CONFIG_SPU_BASE */
2922 static int do_spu_cmd(void)