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>
43 #include <asm/setjmp.h>
46 #include <asm/hvcall.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 static long bus_error_jmp[JMP_BUF_LEN];
75 static int catch_memory_errors;
76 static long *xmon_fault_jmp[NR_CPUS];
78 /* Breakpoint stuff */
80 unsigned long address;
81 unsigned int instr[2];
87 /* Bits in bpt.enabled */
88 #define BP_IABR_TE 1 /* IABR translation enabled */
94 static struct bpt bpts[NBPTS];
95 static struct bpt dabr;
96 static struct bpt *iabr;
97 static unsigned bpinstr = 0x7fe00008; /* trap */
99 #define BP_NUM(bp) ((bp) - bpts + 1)
102 static int cmds(struct pt_regs *);
103 static int mread(unsigned long, void *, int);
104 static int mwrite(unsigned long, void *, int);
105 static int handle_fault(struct pt_regs *);
106 static void byterev(unsigned char *, int);
107 static void memex(void);
108 static int bsesc(void);
109 static void dump(void);
110 static void prdump(unsigned long, long);
111 static int ppc_inst_dump(unsigned long, long, int);
112 static void backtrace(struct pt_regs *);
113 static void excprint(struct pt_regs *);
114 static void prregs(struct pt_regs *);
115 static void memops(int);
116 static void memlocate(void);
117 static void memzcan(void);
118 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
120 int scanhex(unsigned long *valp);
121 static void scannl(void);
122 static int hexdigit(int);
123 void getstring(char *, int);
124 static void flush_input(void);
125 static int inchar(void);
126 static void take_input(char *);
127 static unsigned long read_spr(int);
128 static void write_spr(int, unsigned long);
129 static void super_regs(void);
130 static void remove_bpts(void);
131 static void insert_bpts(void);
132 static void remove_cpu_bpts(void);
133 static void insert_cpu_bpts(void);
134 static struct bpt *at_breakpoint(unsigned long pc);
135 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
136 static int do_step(struct pt_regs *);
137 static void bpt_cmds(void);
138 static void cacheflush(void);
139 static int cpu_cmd(void);
140 static void csum(void);
141 static void bootcmds(void);
142 static void proccall(void);
143 void dump_segments(void);
144 static void symbol_lookup(void);
145 static void xmon_show_stack(unsigned long sp, unsigned long lr,
147 static void xmon_print_symbol(unsigned long address, const char *mid,
149 static const char *getvecname(unsigned long vec);
151 static int do_spu_cmd(void);
154 static void dump_tlb_44x(void);
157 int xmon_no_auto_backtrace;
159 extern void xmon_enter(void);
160 extern void xmon_leave(void);
162 extern void xmon_save_regs(struct pt_regs *);
166 #define REGS_PER_LINE 4
167 #define LAST_VOLATILE 13
170 #define REGS_PER_LINE 8
171 #define LAST_VOLATILE 12
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 = "\
186 b show breakpoints\n\
187 bd set data breakpoint\n\
188 bi set instruction breakpoint\n\
189 bc clear breakpoint\n"
192 c print cpus stopped in xmon\n\
193 c# try to switch to cpu number h (in hex)\n"
198 di dump instructions\n\
199 df dump float values\n\
200 dd dump double values\n\
201 dr dump stream of raw bytes\n\
202 e print exception information\n\
204 la lookup symbol+offset of specified address\n\
205 ls lookup address of specified symbol\n\
206 m examine/change memory\n\
207 mm move a block of memory\n\
208 ms set a block of memory\n\
209 md compare two blocks of memory\n\
210 ml locate a block of memory\n\
211 mz zero a block of memory\n\
212 mi show information about memory allocation\n\
213 p call a procedure\n\
216 #ifdef CONFIG_SPU_BASE
217 " ss stop execution on all spus\n\
218 sr restore execution on stopped spus\n\
219 sf # dump spu fields for spu # (in hex)\n\
220 sd # dump spu local store for spu # (in hex)\n\
221 sdi # disassemble spu local store for spu # (in hex)\n"
223 " S print special registers\n\
225 x exit monitor and recover\n\
226 X exit monitor and dont recover\n"
228 " u dump segment table or SLB\n"
230 #ifdef CONFIG_PPC_STD_MMU_32
231 " u dump segment registers\n"
241 static struct pt_regs *xmon_regs;
243 static inline void sync(void)
245 asm volatile("sync; isync");
248 static inline void store_inst(void *p)
250 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
253 static inline void cflush(void *p)
255 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
258 static inline void cinval(void *p)
260 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
264 * Disable surveillance (the service processor watchdog function)
265 * while we are in xmon.
266 * XXX we should re-enable it when we leave. :)
268 #define SURVEILLANCE_TOKEN 9000
270 static inline void disable_surveillance(void)
272 #ifdef CONFIG_PPC_PSERIES
273 /* Since this can't be a module, args should end up below 4GB. */
274 static struct rtas_args args;
277 * At this point we have got all the cpus we can into
278 * xmon, so there is hopefully no other cpu calling RTAS
279 * at the moment, even though we don't take rtas.lock.
280 * If we did try to take rtas.lock there would be a
281 * real possibility of deadlock.
283 args.token = rtas_token("set-indicator");
284 if (args.token == RTAS_UNKNOWN_SERVICE)
288 args.rets = &args.args[3];
289 args.args[0] = SURVEILLANCE_TOKEN;
292 enter_rtas(__pa(&args));
293 #endif /* CONFIG_PPC_PSERIES */
297 static int xmon_speaker;
299 static void get_output_lock(void)
301 int me = smp_processor_id() + 0x100;
302 int last_speaker = 0, prev;
305 if (xmon_speaker == me)
308 if (xmon_speaker == 0) {
309 last_speaker = cmpxchg(&xmon_speaker, 0, me);
310 if (last_speaker == 0)
314 while (xmon_speaker == last_speaker) {
317 /* hostile takeover */
318 prev = cmpxchg(&xmon_speaker, last_speaker, me);
319 if (prev == last_speaker)
326 static void release_output_lock(void)
332 static int xmon_core(struct pt_regs *regs, int fromipi)
336 long recurse_jmp[JMP_BUF_LEN];
337 unsigned long offset;
342 unsigned long timeout;
345 local_irq_save(flags);
347 bp = in_breakpoint_table(regs->nip, &offset);
349 regs->nip = bp->address + offset;
350 atomic_dec(&bp->ref_count);
356 cpu = smp_processor_id();
357 if (cpu_isset(cpu, cpus_in_xmon)) {
360 printf("cpu 0x%x: Exception %lx %s in xmon, "
361 "returning to main loop\n",
362 cpu, regs->trap, getvecname(TRAP(regs)));
363 release_output_lock();
364 longjmp(xmon_fault_jmp[cpu], 1);
367 if (setjmp(recurse_jmp) != 0) {
368 if (!in_xmon || !xmon_gate) {
370 printf("xmon: WARNING: bad recursive fault "
371 "on cpu 0x%x\n", cpu);
372 release_output_lock();
375 secondary = !(xmon_taken && cpu == xmon_owner);
379 xmon_fault_jmp[cpu] = recurse_jmp;
380 cpu_set(cpu, cpus_in_xmon);
383 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
384 bp = at_breakpoint(regs->nip);
385 if (bp || (regs->msr & MSR_RI) == 0)
392 printf("cpu 0x%x stopped at breakpoint 0x%x (",
394 xmon_print_symbol(regs->nip, " ", ")\n");
396 if ((regs->msr & MSR_RI) == 0)
397 printf("WARNING: exception is not recoverable, "
399 release_output_lock();
404 while (secondary && !xmon_gate) {
408 secondary = test_and_set_bit(0, &in_xmon);
413 if (!secondary && !xmon_gate) {
414 /* we are the first cpu to come in */
415 /* interrupt other cpu(s) */
416 int ncpus = num_online_cpus();
421 smp_send_debugger_break(MSG_ALL_BUT_SELF);
422 /* wait for other cpus to come in */
423 for (timeout = 100000000; timeout != 0; --timeout) {
424 if (cpus_weight(cpus_in_xmon) >= ncpus)
430 disable_surveillance();
431 /* for breakpoint or single step, print the current instr. */
432 if (bp || TRAP(regs) == 0xd00)
433 ppc_inst_dump(regs->nip, 1, 0);
434 printf("enter ? for help\n");
443 if (cpu == xmon_owner) {
444 if (!test_and_set_bit(0, &xmon_taken)) {
449 while (cpu == xmon_owner)
463 /* have switched to some other cpu */
468 cpu_clear(cpu, cpus_in_xmon);
469 xmon_fault_jmp[cpu] = NULL;
471 /* UP is simple... */
473 printf("Exception %lx %s in xmon, returning to main loop\n",
474 regs->trap, getvecname(TRAP(regs)));
475 longjmp(xmon_fault_jmp[0], 1);
477 if (setjmp(recurse_jmp) == 0) {
478 xmon_fault_jmp[0] = recurse_jmp;
482 bp = at_breakpoint(regs->nip);
484 printf("Stopped at breakpoint %x (", BP_NUM(bp));
485 xmon_print_symbol(regs->nip, " ", ")\n");
487 if ((regs->msr & MSR_RI) == 0)
488 printf("WARNING: exception is not recoverable, "
491 disable_surveillance();
492 /* for breakpoint or single step, print the current instr. */
493 if (bp || TRAP(regs) == 0xd00)
494 ppc_inst_dump(regs->nip, 1, 0);
495 printf("enter ? for help\n");
504 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
505 bp = at_breakpoint(regs->nip);
507 int stepped = emulate_step(regs, bp->instr[0]);
509 regs->nip = (unsigned long) &bp->instr[0];
510 atomic_inc(&bp->ref_count);
511 } else if (stepped < 0) {
512 printf("Couldn't single-step %s instruction\n",
513 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
520 local_irq_restore(flags);
522 return cmd != 'X' && cmd != EOF;
525 int xmon(struct pt_regs *excp)
530 xmon_save_regs(®s);
534 return xmon_core(excp, 0);
538 irqreturn_t xmon_irq(int irq, void *d)
541 local_irq_save(flags);
542 printf("Keyboard interrupt\n");
543 xmon(get_irq_regs());
544 local_irq_restore(flags);
548 static int xmon_bpt(struct pt_regs *regs)
551 unsigned long offset;
553 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
556 /* Are we at the trap at bp->instr[1] for some bp? */
557 bp = in_breakpoint_table(regs->nip, &offset);
558 if (bp != NULL && offset == 4) {
559 regs->nip = bp->address + 4;
560 atomic_dec(&bp->ref_count);
564 /* Are we at a breakpoint? */
565 bp = at_breakpoint(regs->nip);
574 static int xmon_sstep(struct pt_regs *regs)
582 static int xmon_dabr_match(struct pt_regs *regs)
584 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
586 if (dabr.enabled == 0)
592 static int xmon_iabr_match(struct pt_regs *regs)
594 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
602 static int xmon_ipi(struct pt_regs *regs)
605 if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
611 static int xmon_fault_handler(struct pt_regs *regs)
614 unsigned long offset;
616 if (in_xmon && catch_memory_errors)
617 handle_fault(regs); /* doesn't return */
619 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
620 bp = in_breakpoint_table(regs->nip, &offset);
622 regs->nip = bp->address + offset;
623 atomic_dec(&bp->ref_count);
630 static struct bpt *at_breakpoint(unsigned long pc)
636 for (i = 0; i < NBPTS; ++i, ++bp)
637 if (bp->enabled && pc == bp->address)
642 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
646 off = nip - (unsigned long) bpts;
647 if (off >= sizeof(bpts))
649 off %= sizeof(struct bpt);
650 if (off != offsetof(struct bpt, instr[0])
651 && off != offsetof(struct bpt, instr[1]))
653 *offp = off - offsetof(struct bpt, instr[0]);
654 return (struct bpt *) (nip - off);
657 static struct bpt *new_breakpoint(unsigned long a)
662 bp = at_breakpoint(a);
666 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
667 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
669 bp->instr[1] = bpinstr;
670 store_inst(&bp->instr[1]);
675 printf("Sorry, no free breakpoints. Please clear one first.\n");
679 static void insert_bpts(void)
685 for (i = 0; i < NBPTS; ++i, ++bp) {
686 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
688 if (mread(bp->address, &bp->instr[0], 4) != 4) {
689 printf("Couldn't read instruction at %lx, "
690 "disabling breakpoint there\n", bp->address);
694 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
695 printf("Breakpoint at %lx is on an mtmsrd or rfid "
696 "instruction, disabling it\n", bp->address);
700 store_inst(&bp->instr[0]);
701 if (bp->enabled & BP_IABR)
703 if (mwrite(bp->address, &bpinstr, 4) != 4) {
704 printf("Couldn't write instruction at %lx, "
705 "disabling breakpoint there\n", bp->address);
706 bp->enabled &= ~BP_TRAP;
709 store_inst((void *)bp->address);
713 static void insert_cpu_bpts(void)
716 set_dabr(dabr.address | (dabr.enabled & 7));
717 if (iabr && cpu_has_feature(CPU_FTR_IABR))
718 mtspr(SPRN_IABR, iabr->address
719 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
722 static void remove_bpts(void)
729 for (i = 0; i < NBPTS; ++i, ++bp) {
730 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
732 if (mread(bp->address, &instr, 4) == 4
734 && mwrite(bp->address, &bp->instr, 4) != 4)
735 printf("Couldn't remove breakpoint at %lx\n",
738 store_inst((void *)bp->address);
742 static void remove_cpu_bpts(void)
745 if (cpu_has_feature(CPU_FTR_IABR))
749 /* Command interpreting routine */
750 static char *last_cmd;
753 cmds(struct pt_regs *excp)
760 if (!xmon_no_auto_backtrace) {
761 xmon_no_auto_backtrace = 1;
762 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
767 printf("%x:", smp_processor_id());
768 #endif /* CONFIG_SMP */
774 if (last_cmd == NULL)
776 take_input(last_cmd);
810 prregs(excp); /* print regs */
825 if (do_spu_cmd() == 0)
834 printf(" <no input ...>\n");
838 xmon_puts(help_string);
856 #ifdef CONFIG_PPC_STD_MMU
867 printf("Unrecognized command: ");
869 if (' ' < cmd && cmd <= '~')
872 printf("\\x%x", cmd);
874 } while (cmd != '\n');
875 printf(" (type ? for help)\n");
882 * Step a single instruction.
883 * Some instructions we emulate, others we execute with MSR_SE set.
885 static int do_step(struct pt_regs *regs)
890 /* check we are in 64-bit kernel mode, translation enabled */
891 if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
892 if (mread(regs->nip, &instr, 4) == 4) {
893 stepped = emulate_step(regs, instr);
895 printf("Couldn't single-step %s instruction\n",
896 (IS_RFID(instr)? "rfid": "mtmsrd"));
900 regs->trap = 0xd00 | (regs->trap & 1);
901 printf("stepped to ");
902 xmon_print_symbol(regs->nip, " ", "\n");
903 ppc_inst_dump(regs->nip, 1, 0);
912 static void bootcmds(void)
918 ppc_md.restart(NULL);
925 static int cpu_cmd(void)
932 if (!scanhex(&cpu)) {
933 /* print cpus waiting or in xmon */
934 printf("cpus stopped:");
936 for (cpu = 0; cpu < NR_CPUS; ++cpu) {
937 if (cpu_isset(cpu, cpus_in_xmon)) {
943 printf("-%x", cpu - 1);
948 printf("-%x", NR_CPUS - 1);
952 /* try to switch to cpu specified */
953 if (!cpu_isset(cpu, cpus_in_xmon)) {
954 printf("cpu 0x%x isn't in xmon\n", cpu);
961 while (!xmon_taken) {
962 if (--timeout == 0) {
963 if (test_and_set_bit(0, &xmon_taken))
965 /* take control back */
967 xmon_owner = smp_processor_id();
968 printf("cpu %u didn't take control\n", cpu);
976 #endif /* CONFIG_SMP */
979 static unsigned short fcstab[256] = {
980 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
981 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
982 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
983 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
984 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
985 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
986 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
987 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
988 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
989 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
990 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
991 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
992 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
993 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
994 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
995 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
996 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
997 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
998 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
999 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1000 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1001 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1002 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1003 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1004 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1005 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1006 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1007 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1008 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1009 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1010 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1011 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1014 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1023 if (!scanhex(&adrs))
1025 if (!scanhex(&ncsum))
1028 for (i = 0; i < ncsum; ++i) {
1029 if (mread(adrs+i, &v, 1) == 0) {
1030 printf("csum stopped at %x\n", adrs+i);
1035 printf("%x\n", fcs);
1039 * Check if this is a suitable place to put a breakpoint.
1041 static long check_bp_loc(unsigned long addr)
1046 if (!is_kernel_addr(addr)) {
1047 printf("Breakpoints may only be placed at kernel addresses\n");
1050 if (!mread(addr, &instr, sizeof(instr))) {
1051 printf("Can't read instruction at address %lx\n", addr);
1054 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1055 printf("Breakpoints may not be placed on mtmsrd or rfid "
1062 static char *breakpoint_help_string =
1063 "Breakpoint command usage:\n"
1064 "b show breakpoints\n"
1065 "b <addr> [cnt] set breakpoint at given instr addr\n"
1066 "bc clear all breakpoints\n"
1067 "bc <n/addr> clear breakpoint number n or at addr\n"
1068 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1069 "bd <addr> [cnt] set hardware data breakpoint\n"
1079 const char badaddr[] = "Only kernel addresses are permitted "
1080 "for breakpoints\n";
1085 case 'd': /* bd - hardware data breakpoint */
1090 else if (cmd == 'w')
1096 if (scanhex(&dabr.address)) {
1097 if (!is_kernel_addr(dabr.address)) {
1102 dabr.enabled = mode | BP_DABR;
1106 case 'i': /* bi - hardware instr breakpoint */
1107 if (!cpu_has_feature(CPU_FTR_IABR)) {
1108 printf("Hardware instruction breakpoint "
1109 "not supported on this cpu\n");
1113 iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1118 if (!check_bp_loc(a))
1120 bp = new_breakpoint(a);
1122 bp->enabled |= BP_IABR | BP_IABR_TE;
1130 /* clear all breakpoints */
1131 for (i = 0; i < NBPTS; ++i)
1132 bpts[i].enabled = 0;
1135 printf("All breakpoints cleared\n");
1139 if (a <= NBPTS && a >= 1) {
1140 /* assume a breakpoint number */
1141 bp = &bpts[a-1]; /* bp nums are 1 based */
1143 /* assume a breakpoint address */
1144 bp = at_breakpoint(a);
1146 printf("No breakpoint at %x\n", a);
1151 printf("Cleared breakpoint %x (", BP_NUM(bp));
1152 xmon_print_symbol(bp->address, " ", ")\n");
1160 printf(breakpoint_help_string);
1165 /* print all breakpoints */
1166 printf(" type address\n");
1168 printf(" data "REG" [", dabr.address);
1169 if (dabr.enabled & 1)
1171 if (dabr.enabled & 2)
1175 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1178 printf("%2x %s ", BP_NUM(bp),
1179 (bp->enabled & BP_IABR)? "inst": "trap");
1180 xmon_print_symbol(bp->address, " ", "\n");
1185 if (!check_bp_loc(a))
1187 bp = new_breakpoint(a);
1189 bp->enabled |= BP_TRAP;
1194 /* Very cheap human name for vector lookup. */
1196 const char *getvecname(unsigned long vec)
1201 case 0x100: ret = "(System Reset)"; break;
1202 case 0x200: ret = "(Machine Check)"; break;
1203 case 0x300: ret = "(Data Access)"; break;
1204 case 0x380: ret = "(Data SLB Access)"; break;
1205 case 0x400: ret = "(Instruction Access)"; break;
1206 case 0x480: ret = "(Instruction SLB Access)"; break;
1207 case 0x500: ret = "(Hardware Interrupt)"; break;
1208 case 0x600: ret = "(Alignment)"; break;
1209 case 0x700: ret = "(Program Check)"; break;
1210 case 0x800: ret = "(FPU Unavailable)"; break;
1211 case 0x900: ret = "(Decrementer)"; break;
1212 case 0xc00: ret = "(System Call)"; break;
1213 case 0xd00: ret = "(Single Step)"; break;
1214 case 0xf00: ret = "(Performance Monitor)"; break;
1215 case 0xf20: ret = "(Altivec Unavailable)"; break;
1216 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1222 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1223 unsigned long *endp)
1225 unsigned long size, offset;
1228 *startp = *endp = 0;
1231 if (setjmp(bus_error_jmp) == 0) {
1232 catch_memory_errors = 1;
1234 name = kallsyms_lookup(pc, &size, &offset, NULL, tmpstr);
1236 *startp = pc - offset;
1237 *endp = pc - offset + size;
1241 catch_memory_errors = 0;
1244 static int xmon_depth_to_print = 64;
1246 #define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1247 #define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long))
1249 #ifdef __powerpc64__
1250 #define REGS_OFFSET 0x70
1252 #define REGS_OFFSET 16
1255 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1259 unsigned long newsp;
1260 unsigned long marker;
1262 struct pt_regs regs;
1265 if (sp < PAGE_OFFSET) {
1267 printf("SP (%lx) is in userspace\n", sp);
1271 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1272 || !mread(sp, &newsp, sizeof(unsigned long))) {
1273 printf("Couldn't read stack frame at %lx\n", sp);
1278 * For the first stack frame, try to work out if
1279 * LR and/or the saved LR value in the bottommost
1280 * stack frame are valid.
1282 if ((pc | lr) != 0) {
1283 unsigned long fnstart, fnend;
1284 unsigned long nextip;
1287 get_function_bounds(pc, &fnstart, &fnend);
1290 mread(newsp + LRSAVE_OFFSET, &nextip,
1291 sizeof(unsigned long));
1293 if (lr < PAGE_OFFSET
1294 || (fnstart <= lr && lr < fnend))
1296 } else if (lr == nextip) {
1298 } else if (lr >= PAGE_OFFSET
1299 && !(fnstart <= lr && lr < fnend)) {
1300 printf("[link register ] ");
1301 xmon_print_symbol(lr, " ", "\n");
1304 printf("["REG"] ", sp);
1305 xmon_print_symbol(ip, " ", " (unreliable)\n");
1310 printf("["REG"] ", sp);
1311 xmon_print_symbol(ip, " ", "\n");
1314 /* Look for "regshere" marker to see if this is
1315 an exception frame. */
1316 if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1317 && marker == STACK_FRAME_REGS_MARKER) {
1318 if (mread(sp + REGS_OFFSET, ®s, sizeof(regs))
1320 printf("Couldn't read registers at %lx\n",
1324 printf("--- Exception: %lx %s at ", regs.trap,
1325 getvecname(TRAP(®s)));
1328 xmon_print_symbol(pc, " ", "\n");
1335 } while (count++ < xmon_depth_to_print);
1338 static void backtrace(struct pt_regs *excp)
1343 xmon_show_stack(sp, 0, 0);
1345 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1349 static void print_bug_trap(struct pt_regs *regs)
1351 const struct bug_entry *bug;
1354 if (regs->msr & MSR_PR)
1355 return; /* not in kernel */
1356 addr = regs->nip; /* address of trap instruction */
1357 if (addr < PAGE_OFFSET)
1359 bug = find_bug(regs->nip);
1362 if (is_warning_bug(bug))
1365 #ifdef CONFIG_DEBUG_BUGVERBOSE
1366 printf("kernel BUG at %s:%u!\n",
1367 bug->file, bug->line);
1369 printf("kernel BUG at %p!\n", (void *)bug->bug_addr);
1373 void excprint(struct pt_regs *fp)
1378 printf("cpu 0x%x: ", smp_processor_id());
1379 #endif /* CONFIG_SMP */
1382 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1384 xmon_print_symbol(fp->nip, ": ", "\n");
1386 printf(" lr: ", fp->link);
1387 xmon_print_symbol(fp->link, ": ", "\n");
1389 printf(" sp: %lx\n", fp->gpr[1]);
1390 printf(" msr: %lx\n", fp->msr);
1392 if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1393 printf(" dar: %lx\n", fp->dar);
1395 printf(" dsisr: %lx\n", fp->dsisr);
1398 printf(" current = 0x%lx\n", current);
1400 printf(" paca = 0x%lx\n", get_paca());
1403 printf(" pid = %ld, comm = %s\n",
1404 current->pid, current->comm);
1411 void prregs(struct pt_regs *fp)
1415 struct pt_regs regs;
1417 if (scanhex(&base)) {
1418 if (setjmp(bus_error_jmp) == 0) {
1419 catch_memory_errors = 1;
1421 regs = *(struct pt_regs *)base;
1425 catch_memory_errors = 0;
1426 printf("*** Error reading registers from "REG"\n",
1430 catch_memory_errors = 0;
1435 if (FULL_REGS(fp)) {
1436 for (n = 0; n < 16; ++n)
1437 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1438 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1440 for (n = 0; n < 7; ++n)
1441 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1442 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1445 for (n = 0; n < 32; ++n) {
1446 printf("R%.2d = %.8x%s", n, fp->gpr[n],
1447 (n & 3) == 3? "\n": " ");
1448 if (n == 12 && !FULL_REGS(fp)) {
1455 xmon_print_symbol(fp->nip, " ", "\n");
1457 xmon_print_symbol(fp->link, " ", "\n");
1458 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
1459 printf("ctr = "REG" xer = "REG" trap = %4lx\n",
1460 fp->ctr, fp->xer, fp->trap);
1462 if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1463 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1466 void cacheflush(void)
1469 unsigned long nflush;
1474 scanhex((void *)&adrs);
1479 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1480 if (setjmp(bus_error_jmp) == 0) {
1481 catch_memory_errors = 1;
1485 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1486 cflush((void *) adrs);
1488 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1489 cinval((void *) adrs);
1492 /* wait a little while to see if we get a machine check */
1495 catch_memory_errors = 0;
1501 unsigned int instrs[2];
1502 unsigned long (*code)(void);
1503 unsigned long ret = -1UL;
1505 unsigned long opd[3];
1507 opd[0] = (unsigned long)instrs;
1510 code = (unsigned long (*)(void)) opd;
1512 code = (unsigned long (*)(void)) instrs;
1515 /* mfspr r3,n; blr */
1516 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1517 instrs[1] = 0x4e800020;
1519 store_inst(instrs+1);
1521 if (setjmp(bus_error_jmp) == 0) {
1522 catch_memory_errors = 1;
1528 /* wait a little while to see if we get a machine check */
1537 write_spr(int n, unsigned long val)
1539 unsigned int instrs[2];
1540 unsigned long (*code)(unsigned long);
1542 unsigned long opd[3];
1544 opd[0] = (unsigned long)instrs;
1547 code = (unsigned long (*)(unsigned long)) opd;
1549 code = (unsigned long (*)(unsigned long)) instrs;
1552 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1553 instrs[1] = 0x4e800020;
1555 store_inst(instrs+1);
1557 if (setjmp(bus_error_jmp) == 0) {
1558 catch_memory_errors = 1;
1564 /* wait a little while to see if we get a machine check */
1570 static unsigned long regno;
1571 extern char exc_prolog;
1572 extern char dec_exc;
1574 void super_regs(void)
1581 unsigned long sp, toc;
1582 asm("mr %0,1" : "=r" (sp) :);
1583 asm("mr %0,2" : "=r" (toc) :);
1585 printf("msr = "REG" sprg0= "REG"\n",
1586 mfmsr(), mfspr(SPRN_SPRG0));
1587 printf("pvr = "REG" sprg1= "REG"\n",
1588 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
1589 printf("dec = "REG" sprg2= "REG"\n",
1590 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1591 printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1592 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
1593 #ifdef CONFIG_PPC_ISERIES
1594 if (firmware_has_feature(FW_FEATURE_ISERIES)) {
1595 struct paca_struct *ptrPaca;
1596 struct lppaca *ptrLpPaca;
1598 /* Dump out relevant Paca data areas. */
1600 ptrPaca = get_paca();
1602 printf(" Local Processor Control Area (LpPaca): \n");
1603 ptrLpPaca = ptrPaca->lppaca_ptr;
1604 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1605 ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
1606 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1607 ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
1608 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
1618 val = read_spr(regno);
1620 write_spr(regno, val);
1623 printf("spr %lx = %lx\n", regno, read_spr(regno));
1630 * Stuff for reading and writing memory safely
1633 mread(unsigned long adrs, void *buf, int size)
1639 if (setjmp(bus_error_jmp) == 0) {
1640 catch_memory_errors = 1;
1646 *(u16 *)q = *(u16 *)p;
1649 *(u32 *)q = *(u32 *)p;
1652 *(u64 *)q = *(u64 *)p;
1655 for( ; n < size; ++n) {
1661 /* wait a little while to see if we get a machine check */
1665 catch_memory_errors = 0;
1670 mwrite(unsigned long adrs, void *buf, int size)
1676 if (setjmp(bus_error_jmp) == 0) {
1677 catch_memory_errors = 1;
1683 *(u16 *)p = *(u16 *)q;
1686 *(u32 *)p = *(u32 *)q;
1689 *(u64 *)p = *(u64 *)q;
1692 for ( ; n < size; ++n) {
1698 /* wait a little while to see if we get a machine check */
1702 printf("*** Error writing address %x\n", adrs + n);
1704 catch_memory_errors = 0;
1708 static int fault_type;
1709 static int fault_except;
1710 static char *fault_chars[] = { "--", "**", "##" };
1712 static int handle_fault(struct pt_regs *regs)
1714 fault_except = TRAP(regs);
1715 switch (TRAP(regs)) {
1727 longjmp(bus_error_jmp, 1);
1732 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1735 byterev(unsigned char *val, int size)
1741 SWAP(val[0], val[1], t);
1744 SWAP(val[0], val[3], t);
1745 SWAP(val[1], val[2], t);
1747 case 8: /* is there really any use for this? */
1748 SWAP(val[0], val[7], t);
1749 SWAP(val[1], val[6], t);
1750 SWAP(val[2], val[5], t);
1751 SWAP(val[3], val[4], t);
1759 static char *memex_help_string =
1760 "Memory examine command usage:\n"
1761 "m [addr] [flags] examine/change memory\n"
1762 " addr is optional. will start where left off.\n"
1763 " flags may include chars from this set:\n"
1764 " b modify by bytes (default)\n"
1765 " w modify by words (2 byte)\n"
1766 " l modify by longs (4 byte)\n"
1767 " d modify by doubleword (8 byte)\n"
1768 " r toggle reverse byte order mode\n"
1769 " n do not read memory (for i/o spaces)\n"
1770 " . ok to read (default)\n"
1771 "NOTE: flags are saved as defaults\n"
1774 static char *memex_subcmd_help_string =
1775 "Memory examine subcommands:\n"
1776 " hexval write this val to current location\n"
1777 " 'string' write chars from string to this location\n"
1778 " ' increment address\n"
1779 " ^ decrement address\n"
1780 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1781 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1782 " ` clear no-read flag\n"
1783 " ; stay at this addr\n"
1784 " v change to byte mode\n"
1785 " w change to word (2 byte) mode\n"
1786 " l change to long (4 byte) mode\n"
1787 " u change to doubleword (8 byte) mode\n"
1788 " m addr change current addr\n"
1789 " n toggle no-read flag\n"
1790 " r toggle byte reverse flag\n"
1791 " < count back up count bytes\n"
1792 " > count skip forward count bytes\n"
1793 " x exit this mode\n"
1799 int cmd, inc, i, nslash;
1801 unsigned char val[16];
1803 scanhex((void *)&adrs);
1806 printf(memex_help_string);
1812 while ((cmd = skipbl()) != '\n') {
1814 case 'b': size = 1; break;
1815 case 'w': size = 2; break;
1816 case 'l': size = 4; break;
1817 case 'd': size = 8; break;
1818 case 'r': brev = !brev; break;
1819 case 'n': mnoread = 1; break;
1820 case '.': mnoread = 0; break;
1829 n = mread(adrs, val, size);
1830 printf(REG"%c", adrs, brev? 'r': ' ');
1835 for (i = 0; i < n; ++i)
1836 printf("%.2x", val[i]);
1837 for (; i < size; ++i)
1838 printf("%s", fault_chars[fault_type]);
1845 for (i = 0; i < size; ++i)
1846 val[i] = n >> (i * 8);
1849 mwrite(adrs, val, size);
1862 else if( n == '\'' )
1864 for (i = 0; i < size; ++i)
1865 val[i] = n >> (i * 8);
1868 mwrite(adrs, val, size);
1905 adrs -= 1 << nslash;
1909 adrs += 1 << nslash;
1913 adrs += 1 << -nslash;
1917 adrs -= 1 << -nslash;
1920 scanhex((void *)&adrs);
1939 printf(memex_subcmd_help_string);
1954 case 'n': c = '\n'; break;
1955 case 'r': c = '\r'; break;
1956 case 'b': c = '\b'; break;
1957 case 't': c = '\t'; break;
1962 static void xmon_rawdump (unsigned long adrs, long ndump)
1965 unsigned char temp[16];
1967 for (n = ndump; n > 0;) {
1969 nr = mread(adrs, temp, r);
1971 for (m = 0; m < r; ++m) {
1973 printf("%.2x", temp[m]);
1975 printf("%s", fault_chars[fault_type]);
1984 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
1985 || ('a' <= (c) && (c) <= 'f') \
1986 || ('A' <= (c) && (c) <= 'F'))
1993 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
1995 scanhex((void *)&adrs);
2002 else if (nidump > MAX_DUMP)
2004 adrs += ppc_inst_dump(adrs, nidump, 1);
2006 } else if (c == 'r') {
2010 xmon_rawdump(adrs, ndump);
2017 else if (ndump > MAX_DUMP)
2019 prdump(adrs, ndump);
2026 prdump(unsigned long adrs, long ndump)
2028 long n, m, c, r, nr;
2029 unsigned char temp[16];
2031 for (n = ndump; n > 0;) {
2035 nr = mread(adrs, temp, r);
2037 for (m = 0; m < r; ++m) {
2038 if ((m & (sizeof(long) - 1)) == 0 && m > 0)
2041 printf("%.2x", temp[m]);
2043 printf("%s", fault_chars[fault_type]);
2045 for (; m < 16; ++m) {
2046 if ((m & (sizeof(long) - 1)) == 0)
2051 for (m = 0; m < r; ++m) {
2054 putchar(' ' <= c && c <= '~'? c: '.');
2067 typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr);
2070 generic_inst_dump(unsigned long adr, long count, int praddr,
2071 instruction_dump_func dump_func)
2074 unsigned long first_adr;
2075 unsigned long inst, last_inst = 0;
2076 unsigned char val[4];
2079 for (first_adr = adr; count > 0; --count, adr += 4) {
2080 nr = mread(adr, val, 4);
2083 const char *x = fault_chars[fault_type];
2084 printf(REG" %s%s%s%s\n", adr, x, x, x, x);
2088 inst = GETWORD(val);
2089 if (adr > first_adr && inst == last_inst) {
2099 printf(REG" %.8x", adr, inst);
2101 dump_func(inst, adr);
2104 return adr - first_adr;
2108 ppc_inst_dump(unsigned long adr, long count, int praddr)
2110 return generic_inst_dump(adr, count, praddr, print_insn_powerpc);
2114 print_address(unsigned long addr)
2116 xmon_print_symbol(addr, "\t# ", "");
2121 * Memory operations - move, set, print differences
2123 static unsigned long mdest; /* destination address */
2124 static unsigned long msrc; /* source address */
2125 static unsigned long mval; /* byte value to set memory to */
2126 static unsigned long mcount; /* # bytes to affect */
2127 static unsigned long mdiffs; /* max # differences to print */
2132 scanhex((void *)&mdest);
2133 if( termch != '\n' )
2135 scanhex((void *)(cmd == 's'? &mval: &msrc));
2136 if( termch != '\n' )
2138 scanhex((void *)&mcount);
2141 memmove((void *)mdest, (void *)msrc, mcount);
2144 memset((void *)mdest, mval, mcount);
2147 if( termch != '\n' )
2149 scanhex((void *)&mdiffs);
2150 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2156 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2161 for( n = nb; n > 0; --n )
2162 if( *p1++ != *p2++ )
2163 if( ++prt <= maxpr )
2164 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2165 p1[-1], p2 - 1, p2[-1]);
2167 printf("Total of %d differences\n", prt);
2170 static unsigned mend;
2171 static unsigned mask;
2177 unsigned char val[4];
2180 scanhex((void *)&mdest);
2181 if (termch != '\n') {
2183 scanhex((void *)&mend);
2184 if (termch != '\n') {
2186 scanhex((void *)&mval);
2188 if (termch != '\n') termch = 0;
2189 scanhex((void *)&mask);
2193 for (a = mdest; a < mend; a += 4) {
2194 if (mread(a, val, 4) == 4
2195 && ((GETWORD(val) ^ mval) & mask) == 0) {
2196 printf("%.16x: %.16x\n", a, GETWORD(val));
2203 static unsigned long mskip = 0x1000;
2204 static unsigned long mlim = 0xffffffff;
2214 if (termch != '\n') termch = 0;
2216 if (termch != '\n') termch = 0;
2219 for (a = mdest; a < mlim; a += mskip) {
2220 ok = mread(a, &v, 1);
2222 printf("%.8x .. ", a);
2223 } else if (!ok && ook)
2224 printf("%.8x\n", a - mskip);
2230 printf("%.8x\n", a - mskip);
2235 unsigned long args[8];
2238 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2239 unsigned long, unsigned long, unsigned long,
2240 unsigned long, unsigned long, unsigned long);
2243 if (!scanhex(&adrs))
2247 for (i = 0; i < 8; ++i)
2249 for (i = 0; i < 8; ++i) {
2250 if (!scanhex(&args[i]) || termch == '\n')
2254 func = (callfunc_t) adrs;
2256 if (setjmp(bus_error_jmp) == 0) {
2257 catch_memory_errors = 1;
2259 ret = func(args[0], args[1], args[2], args[3],
2260 args[4], args[5], args[6], args[7]);
2262 printf("return value is %x\n", ret);
2264 printf("*** %x exception occurred\n", fault_except);
2266 catch_memory_errors = 0;
2269 /* Input scanning routines */
2280 while( c == ' ' || c == '\t' )
2286 static char *regnames[N_PTREGS] = {
2287 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2288 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2289 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2290 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2291 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2297 "trap", "dar", "dsisr", "res"
2301 scanhex(unsigned long *vp)
2308 /* parse register name */
2312 for (i = 0; i < sizeof(regname) - 1; ++i) {
2321 for (i = 0; i < N_PTREGS; ++i) {
2322 if (strcmp(regnames[i], regname) == 0) {
2323 if (xmon_regs == NULL) {
2324 printf("regs not available\n");
2327 *vp = ((unsigned long *)xmon_regs)[i];
2331 printf("invalid register name '%%%s'\n", regname);
2335 /* skip leading "0x" if any */
2349 } else if (c == '$') {
2351 for (i=0; i<63; i++) {
2361 if (setjmp(bus_error_jmp) == 0) {
2362 catch_memory_errors = 1;
2364 *vp = kallsyms_lookup_name(tmpstr);
2367 catch_memory_errors = 0;
2369 printf("unknown symbol '%s'\n", tmpstr);
2404 if( '0' <= c && c <= '9' )
2406 if( 'A' <= c && c <= 'F' )
2407 return c - ('A' - 10);
2408 if( 'a' <= c && c <= 'f' )
2409 return c - ('a' - 10);
2414 getstring(char *s, int size)
2425 } while( c != ' ' && c != '\t' && c != '\n' );
2430 static char line[256];
2431 static char *lineptr;
2442 if (lineptr == NULL || *lineptr == 0) {
2443 if (xmon_gets(line, sizeof(line)) == NULL) {
2453 take_input(char *str)
2462 int type = inchar();
2464 static char tmp[64];
2469 xmon_print_symbol(addr, ": ", "\n");
2474 if (setjmp(bus_error_jmp) == 0) {
2475 catch_memory_errors = 1;
2477 addr = kallsyms_lookup_name(tmp);
2479 printf("%s: %lx\n", tmp, addr);
2481 printf("Symbol '%s' not found.\n", tmp);
2484 catch_memory_errors = 0;
2491 /* Print an address in numeric and symbolic form (if possible) */
2492 static void xmon_print_symbol(unsigned long address, const char *mid,
2496 const char *name = NULL;
2497 unsigned long offset, size;
2499 printf(REG, address);
2500 if (setjmp(bus_error_jmp) == 0) {
2501 catch_memory_errors = 1;
2503 name = kallsyms_lookup(address, &size, &offset, &modname,
2506 /* wait a little while to see if we get a machine check */
2510 catch_memory_errors = 0;
2513 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2515 printf(" [%s]", modname);
2517 printf("%s", after);
2521 static void dump_slb(void)
2524 unsigned long esid,vsid,valid;
2527 printf("SLB contents of cpu %x\n", smp_processor_id());
2529 for (i = 0; i < mmu_slb_size; i++) {
2530 asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i));
2531 asm volatile("slbmfev %0,%1" : "=r" (vsid) : "r" (i));
2532 valid = (esid & SLB_ESID_V);
2533 if (valid | esid | vsid) {
2534 printf("%02d %016lx %016lx", i, esid, vsid);
2536 llp = vsid & SLB_VSID_LLP;
2537 if (vsid & SLB_VSID_B_1T) {
2538 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
2540 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T,
2543 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
2545 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT,
2554 static void dump_stab(void)
2557 unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2559 printf("Segment table contents of cpu %x\n", smp_processor_id());
2561 for (i = 0; i < PAGE_SIZE/16; i++) {
2568 printf("%03d %016lx ", i, a);
2569 printf("%016lx\n", b);
2574 void dump_segments(void)
2576 if (cpu_has_feature(CPU_FTR_SLB))
2583 #ifdef CONFIG_PPC_STD_MMU_32
2584 void dump_segments(void)
2589 for (i = 0; i < 16; ++i)
2590 printf(" %x", mfsrin(i));
2596 static void dump_tlb_44x(void)
2600 for (i = 0; i < PPC44x_TLB_SIZE; i++) {
2601 unsigned long w0,w1,w2;
2602 asm volatile("tlbre %0,%1,0" : "=r" (w0) : "r" (i));
2603 asm volatile("tlbre %0,%1,1" : "=r" (w1) : "r" (i));
2604 asm volatile("tlbre %0,%1,2" : "=r" (w2) : "r" (i));
2605 printf("[%02x] %08x %08x %08x ", i, w0, w1, w2);
2606 if (w0 & PPC44x_TLB_VALID) {
2607 printf("V %08x -> %01x%08x %c%c%c%c%c",
2608 w0 & PPC44x_TLB_EPN_MASK,
2609 w1 & PPC44x_TLB_ERPN_MASK,
2610 w1 & PPC44x_TLB_RPN_MASK,
2611 (w2 & PPC44x_TLB_W) ? 'W' : 'w',
2612 (w2 & PPC44x_TLB_I) ? 'I' : 'i',
2613 (w2 & PPC44x_TLB_M) ? 'M' : 'm',
2614 (w2 & PPC44x_TLB_G) ? 'G' : 'g',
2615 (w2 & PPC44x_TLB_E) ? 'E' : 'e');
2620 #endif /* CONFIG_44x */
2621 void xmon_init(int enable)
2623 #ifdef CONFIG_PPC_ISERIES
2624 if (firmware_has_feature(FW_FEATURE_ISERIES))
2629 __debugger_ipi = xmon_ipi;
2630 __debugger_bpt = xmon_bpt;
2631 __debugger_sstep = xmon_sstep;
2632 __debugger_iabr_match = xmon_iabr_match;
2633 __debugger_dabr_match = xmon_dabr_match;
2634 __debugger_fault_handler = xmon_fault_handler;
2637 __debugger_ipi = NULL;
2638 __debugger_bpt = NULL;
2639 __debugger_sstep = NULL;
2640 __debugger_iabr_match = NULL;
2641 __debugger_dabr_match = NULL;
2642 __debugger_fault_handler = NULL;
2647 #ifdef CONFIG_MAGIC_SYSRQ
2648 static void sysrq_handle_xmon(int key, struct tty_struct *tty)
2650 /* ensure xmon is enabled */
2652 debugger(get_irq_regs());
2655 static struct sysrq_key_op sysrq_xmon_op =
2657 .handler = sysrq_handle_xmon,
2659 .action_msg = "Entering xmon",
2662 static int __init setup_xmon_sysrq(void)
2664 #ifdef CONFIG_PPC_ISERIES
2665 if (firmware_has_feature(FW_FEATURE_ISERIES))
2668 register_sysrq_key('x', &sysrq_xmon_op);
2671 __initcall(setup_xmon_sysrq);
2672 #endif /* CONFIG_MAGIC_SYSRQ */
2674 static int __initdata xmon_early, xmon_off;
2676 static int __init early_parse_xmon(char *p)
2678 if (!p || strncmp(p, "early", 5) == 0) {
2679 /* just "xmon" is equivalent to "xmon=early" */
2682 } else if (strncmp(p, "on", 2) == 0)
2684 else if (strncmp(p, "off", 3) == 0)
2686 else if (strncmp(p, "nobt", 4) == 0)
2687 xmon_no_auto_backtrace = 1;
2693 early_param("xmon", early_parse_xmon);
2695 void __init xmon_setup(void)
2697 #ifdef CONFIG_XMON_DEFAULT
2705 #ifdef CONFIG_SPU_BASE
2709 u64 saved_mfc_sr1_RW;
2710 u32 saved_spu_runcntl_RW;
2711 unsigned long dump_addr;
2715 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
2717 static struct spu_info spu_info[XMON_NUM_SPUS];
2719 void xmon_register_spus(struct list_head *list)
2723 list_for_each_entry(spu, list, full_list) {
2724 if (spu->number >= XMON_NUM_SPUS) {
2729 spu_info[spu->number].spu = spu;
2730 spu_info[spu->number].stopped_ok = 0;
2731 spu_info[spu->number].dump_addr = (unsigned long)
2732 spu_info[spu->number].spu->local_store;
2736 static void stop_spus(void)
2742 for (i = 0; i < XMON_NUM_SPUS; i++) {
2743 if (!spu_info[i].spu)
2746 if (setjmp(bus_error_jmp) == 0) {
2747 catch_memory_errors = 1;
2750 spu = spu_info[i].spu;
2752 spu_info[i].saved_spu_runcntl_RW =
2753 in_be32(&spu->problem->spu_runcntl_RW);
2755 tmp = spu_mfc_sr1_get(spu);
2756 spu_info[i].saved_mfc_sr1_RW = tmp;
2758 tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
2759 spu_mfc_sr1_set(spu, tmp);
2764 spu_info[i].stopped_ok = 1;
2766 printf("Stopped spu %.2d (was %s)\n", i,
2767 spu_info[i].saved_spu_runcntl_RW ?
2768 "running" : "stopped");
2770 catch_memory_errors = 0;
2771 printf("*** Error stopping spu %.2d\n", i);
2773 catch_memory_errors = 0;
2777 static void restart_spus(void)
2782 for (i = 0; i < XMON_NUM_SPUS; i++) {
2783 if (!spu_info[i].spu)
2786 if (!spu_info[i].stopped_ok) {
2787 printf("*** Error, spu %d was not successfully stopped"
2788 ", not restarting\n", i);
2792 if (setjmp(bus_error_jmp) == 0) {
2793 catch_memory_errors = 1;
2796 spu = spu_info[i].spu;
2797 spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
2798 out_be32(&spu->problem->spu_runcntl_RW,
2799 spu_info[i].saved_spu_runcntl_RW);
2804 printf("Restarted spu %.2d\n", i);
2806 catch_memory_errors = 0;
2807 printf("*** Error restarting spu %.2d\n", i);
2809 catch_memory_errors = 0;
2813 #define DUMP_WIDTH 23
2814 #define DUMP_VALUE(format, field, value) \
2816 if (setjmp(bus_error_jmp) == 0) { \
2817 catch_memory_errors = 1; \
2819 printf(" %-*s = "format"\n", DUMP_WIDTH, \
2824 catch_memory_errors = 0; \
2825 printf(" %-*s = *** Error reading field.\n", \
2826 DUMP_WIDTH, #field); \
2828 catch_memory_errors = 0; \
2831 #define DUMP_FIELD(obj, format, field) \
2832 DUMP_VALUE(format, field, obj->field)
2834 static void dump_spu_fields(struct spu *spu)
2836 printf("Dumping spu fields at address %p:\n", spu);
2838 DUMP_FIELD(spu, "0x%x", number);
2839 DUMP_FIELD(spu, "%s", name);
2840 DUMP_FIELD(spu, "0x%lx", local_store_phys);
2841 DUMP_FIELD(spu, "0x%p", local_store);
2842 DUMP_FIELD(spu, "0x%lx", ls_size);
2843 DUMP_FIELD(spu, "0x%x", node);
2844 DUMP_FIELD(spu, "0x%lx", flags);
2845 DUMP_FIELD(spu, "%d", class_0_pending);
2846 DUMP_FIELD(spu, "0x%lx", class_0_dar);
2847 DUMP_FIELD(spu, "0x%lx", class_1_dar);
2848 DUMP_FIELD(spu, "0x%lx", class_1_dsisr);
2849 DUMP_FIELD(spu, "0x%lx", irqs[0]);
2850 DUMP_FIELD(spu, "0x%lx", irqs[1]);
2851 DUMP_FIELD(spu, "0x%lx", irqs[2]);
2852 DUMP_FIELD(spu, "0x%x", slb_replace);
2853 DUMP_FIELD(spu, "%d", pid);
2854 DUMP_FIELD(spu, "0x%p", mm);
2855 DUMP_FIELD(spu, "0x%p", ctx);
2856 DUMP_FIELD(spu, "0x%p", rq);
2857 DUMP_FIELD(spu, "0x%p", timestamp);
2858 DUMP_FIELD(spu, "0x%lx", problem_phys);
2859 DUMP_FIELD(spu, "0x%p", problem);
2860 DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
2861 in_be32(&spu->problem->spu_runcntl_RW));
2862 DUMP_VALUE("0x%x", problem->spu_status_R,
2863 in_be32(&spu->problem->spu_status_R));
2864 DUMP_VALUE("0x%x", problem->spu_npc_RW,
2865 in_be32(&spu->problem->spu_npc_RW));
2866 DUMP_FIELD(spu, "0x%p", priv2);
2867 DUMP_FIELD(spu, "0x%p", pdata);
2871 spu_inst_dump(unsigned long adr, long count, int praddr)
2873 return generic_inst_dump(adr, count, praddr, print_insn_spu);
2876 static void dump_spu_ls(unsigned long num, int subcmd)
2878 unsigned long offset, addr, ls_addr;
2880 if (setjmp(bus_error_jmp) == 0) {
2881 catch_memory_errors = 1;
2883 ls_addr = (unsigned long)spu_info[num].spu->local_store;
2887 catch_memory_errors = 0;
2888 printf("*** Error: accessing spu info for spu %d\n", num);
2891 catch_memory_errors = 0;
2893 if (scanhex(&offset))
2894 addr = ls_addr + offset;
2896 addr = spu_info[num].dump_addr;
2898 if (addr >= ls_addr + LS_SIZE) {
2899 printf("*** Error: address outside of local store\n");
2905 addr += spu_inst_dump(addr, 16, 1);
2915 spu_info[num].dump_addr = addr;
2918 static int do_spu_cmd(void)
2920 static unsigned long num = 0;
2921 int cmd, subcmd = 0;
2933 if (isxdigit(subcmd) || subcmd == '\n')
2937 if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
2938 printf("*** Error: invalid spu number\n");
2944 dump_spu_fields(spu_info[num].spu);
2947 dump_spu_ls(num, subcmd);
2958 #else /* ! CONFIG_SPU_BASE */
2959 static int do_spu_cmd(void)