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;
1247 #define LRSAVE_OFFSET 0x10
1248 #define REG_FRAME_MARKER 0x7265677368657265ul /* "regshere" */
1249 #define MARKER_OFFSET 0x60
1250 #define REGS_OFFSET 0x70
1252 #define LRSAVE_OFFSET 4
1253 #define REG_FRAME_MARKER 0x72656773
1254 #define MARKER_OFFSET 8
1255 #define REGS_OFFSET 16
1258 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1262 unsigned long newsp;
1263 unsigned long marker;
1265 struct pt_regs regs;
1268 if (sp < PAGE_OFFSET) {
1270 printf("SP (%lx) is in userspace\n", sp);
1274 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1275 || !mread(sp, &newsp, sizeof(unsigned long))) {
1276 printf("Couldn't read stack frame at %lx\n", sp);
1281 * For the first stack frame, try to work out if
1282 * LR and/or the saved LR value in the bottommost
1283 * stack frame are valid.
1285 if ((pc | lr) != 0) {
1286 unsigned long fnstart, fnend;
1287 unsigned long nextip;
1290 get_function_bounds(pc, &fnstart, &fnend);
1293 mread(newsp + LRSAVE_OFFSET, &nextip,
1294 sizeof(unsigned long));
1296 if (lr < PAGE_OFFSET
1297 || (fnstart <= lr && lr < fnend))
1299 } else if (lr == nextip) {
1301 } else if (lr >= PAGE_OFFSET
1302 && !(fnstart <= lr && lr < fnend)) {
1303 printf("[link register ] ");
1304 xmon_print_symbol(lr, " ", "\n");
1307 printf("["REG"] ", sp);
1308 xmon_print_symbol(ip, " ", " (unreliable)\n");
1313 printf("["REG"] ", sp);
1314 xmon_print_symbol(ip, " ", "\n");
1317 /* Look for "regshere" marker to see if this is
1318 an exception frame. */
1319 if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1320 && marker == REG_FRAME_MARKER) {
1321 if (mread(sp + REGS_OFFSET, ®s, sizeof(regs))
1323 printf("Couldn't read registers at %lx\n",
1327 printf("--- Exception: %lx %s at ", regs.trap,
1328 getvecname(TRAP(®s)));
1331 xmon_print_symbol(pc, " ", "\n");
1338 } while (count++ < xmon_depth_to_print);
1341 static void backtrace(struct pt_regs *excp)
1346 xmon_show_stack(sp, 0, 0);
1348 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1352 static void print_bug_trap(struct pt_regs *regs)
1354 const struct bug_entry *bug;
1357 if (regs->msr & MSR_PR)
1358 return; /* not in kernel */
1359 addr = regs->nip; /* address of trap instruction */
1360 if (addr < PAGE_OFFSET)
1362 bug = find_bug(regs->nip);
1365 if (is_warning_bug(bug))
1368 #ifdef CONFIG_DEBUG_BUGVERBOSE
1369 printf("kernel BUG at %s:%u!\n",
1370 bug->file, bug->line);
1372 printf("kernel BUG at %p!\n", (void *)bug->bug_addr);
1376 void excprint(struct pt_regs *fp)
1381 printf("cpu 0x%x: ", smp_processor_id());
1382 #endif /* CONFIG_SMP */
1385 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1387 xmon_print_symbol(fp->nip, ": ", "\n");
1389 printf(" lr: ", fp->link);
1390 xmon_print_symbol(fp->link, ": ", "\n");
1392 printf(" sp: %lx\n", fp->gpr[1]);
1393 printf(" msr: %lx\n", fp->msr);
1395 if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1396 printf(" dar: %lx\n", fp->dar);
1398 printf(" dsisr: %lx\n", fp->dsisr);
1401 printf(" current = 0x%lx\n", current);
1403 printf(" paca = 0x%lx\n", get_paca());
1406 printf(" pid = %ld, comm = %s\n",
1407 current->pid, current->comm);
1414 void prregs(struct pt_regs *fp)
1418 struct pt_regs regs;
1420 if (scanhex(&base)) {
1421 if (setjmp(bus_error_jmp) == 0) {
1422 catch_memory_errors = 1;
1424 regs = *(struct pt_regs *)base;
1428 catch_memory_errors = 0;
1429 printf("*** Error reading registers from "REG"\n",
1433 catch_memory_errors = 0;
1438 if (FULL_REGS(fp)) {
1439 for (n = 0; n < 16; ++n)
1440 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1441 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1443 for (n = 0; n < 7; ++n)
1444 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1445 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1448 for (n = 0; n < 32; ++n) {
1449 printf("R%.2d = %.8x%s", n, fp->gpr[n],
1450 (n & 3) == 3? "\n": " ");
1451 if (n == 12 && !FULL_REGS(fp)) {
1458 xmon_print_symbol(fp->nip, " ", "\n");
1460 xmon_print_symbol(fp->link, " ", "\n");
1461 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
1462 printf("ctr = "REG" xer = "REG" trap = %4lx\n",
1463 fp->ctr, fp->xer, fp->trap);
1465 if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1466 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1469 void cacheflush(void)
1472 unsigned long nflush;
1477 scanhex((void *)&adrs);
1482 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1483 if (setjmp(bus_error_jmp) == 0) {
1484 catch_memory_errors = 1;
1488 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1489 cflush((void *) adrs);
1491 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1492 cinval((void *) adrs);
1495 /* wait a little while to see if we get a machine check */
1498 catch_memory_errors = 0;
1504 unsigned int instrs[2];
1505 unsigned long (*code)(void);
1506 unsigned long ret = -1UL;
1508 unsigned long opd[3];
1510 opd[0] = (unsigned long)instrs;
1513 code = (unsigned long (*)(void)) opd;
1515 code = (unsigned long (*)(void)) instrs;
1518 /* mfspr r3,n; blr */
1519 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1520 instrs[1] = 0x4e800020;
1522 store_inst(instrs+1);
1524 if (setjmp(bus_error_jmp) == 0) {
1525 catch_memory_errors = 1;
1531 /* wait a little while to see if we get a machine check */
1540 write_spr(int n, unsigned long val)
1542 unsigned int instrs[2];
1543 unsigned long (*code)(unsigned long);
1545 unsigned long opd[3];
1547 opd[0] = (unsigned long)instrs;
1550 code = (unsigned long (*)(unsigned long)) opd;
1552 code = (unsigned long (*)(unsigned long)) instrs;
1555 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1556 instrs[1] = 0x4e800020;
1558 store_inst(instrs+1);
1560 if (setjmp(bus_error_jmp) == 0) {
1561 catch_memory_errors = 1;
1567 /* wait a little while to see if we get a machine check */
1573 static unsigned long regno;
1574 extern char exc_prolog;
1575 extern char dec_exc;
1577 void super_regs(void)
1584 unsigned long sp, toc;
1585 asm("mr %0,1" : "=r" (sp) :);
1586 asm("mr %0,2" : "=r" (toc) :);
1588 printf("msr = "REG" sprg0= "REG"\n",
1589 mfmsr(), mfspr(SPRN_SPRG0));
1590 printf("pvr = "REG" sprg1= "REG"\n",
1591 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
1592 printf("dec = "REG" sprg2= "REG"\n",
1593 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1594 printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1595 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
1596 #ifdef CONFIG_PPC_ISERIES
1597 if (firmware_has_feature(FW_FEATURE_ISERIES)) {
1598 struct paca_struct *ptrPaca;
1599 struct lppaca *ptrLpPaca;
1601 /* Dump out relevant Paca data areas. */
1603 ptrPaca = get_paca();
1605 printf(" Local Processor Control Area (LpPaca): \n");
1606 ptrLpPaca = ptrPaca->lppaca_ptr;
1607 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1608 ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
1609 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1610 ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
1611 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
1621 val = read_spr(regno);
1623 write_spr(regno, val);
1626 printf("spr %lx = %lx\n", regno, read_spr(regno));
1633 * Stuff for reading and writing memory safely
1636 mread(unsigned long adrs, void *buf, int size)
1642 if (setjmp(bus_error_jmp) == 0) {
1643 catch_memory_errors = 1;
1649 *(u16 *)q = *(u16 *)p;
1652 *(u32 *)q = *(u32 *)p;
1655 *(u64 *)q = *(u64 *)p;
1658 for( ; n < size; ++n) {
1664 /* wait a little while to see if we get a machine check */
1668 catch_memory_errors = 0;
1673 mwrite(unsigned long adrs, void *buf, int size)
1679 if (setjmp(bus_error_jmp) == 0) {
1680 catch_memory_errors = 1;
1686 *(u16 *)p = *(u16 *)q;
1689 *(u32 *)p = *(u32 *)q;
1692 *(u64 *)p = *(u64 *)q;
1695 for ( ; n < size; ++n) {
1701 /* wait a little while to see if we get a machine check */
1705 printf("*** Error writing address %x\n", adrs + n);
1707 catch_memory_errors = 0;
1711 static int fault_type;
1712 static int fault_except;
1713 static char *fault_chars[] = { "--", "**", "##" };
1715 static int handle_fault(struct pt_regs *regs)
1717 fault_except = TRAP(regs);
1718 switch (TRAP(regs)) {
1730 longjmp(bus_error_jmp, 1);
1735 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1738 byterev(unsigned char *val, int size)
1744 SWAP(val[0], val[1], t);
1747 SWAP(val[0], val[3], t);
1748 SWAP(val[1], val[2], t);
1750 case 8: /* is there really any use for this? */
1751 SWAP(val[0], val[7], t);
1752 SWAP(val[1], val[6], t);
1753 SWAP(val[2], val[5], t);
1754 SWAP(val[3], val[4], t);
1762 static char *memex_help_string =
1763 "Memory examine command usage:\n"
1764 "m [addr] [flags] examine/change memory\n"
1765 " addr is optional. will start where left off.\n"
1766 " flags may include chars from this set:\n"
1767 " b modify by bytes (default)\n"
1768 " w modify by words (2 byte)\n"
1769 " l modify by longs (4 byte)\n"
1770 " d modify by doubleword (8 byte)\n"
1771 " r toggle reverse byte order mode\n"
1772 " n do not read memory (for i/o spaces)\n"
1773 " . ok to read (default)\n"
1774 "NOTE: flags are saved as defaults\n"
1777 static char *memex_subcmd_help_string =
1778 "Memory examine subcommands:\n"
1779 " hexval write this val to current location\n"
1780 " 'string' write chars from string to this location\n"
1781 " ' increment address\n"
1782 " ^ decrement address\n"
1783 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1784 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1785 " ` clear no-read flag\n"
1786 " ; stay at this addr\n"
1787 " v change to byte mode\n"
1788 " w change to word (2 byte) mode\n"
1789 " l change to long (4 byte) mode\n"
1790 " u change to doubleword (8 byte) mode\n"
1791 " m addr change current addr\n"
1792 " n toggle no-read flag\n"
1793 " r toggle byte reverse flag\n"
1794 " < count back up count bytes\n"
1795 " > count skip forward count bytes\n"
1796 " x exit this mode\n"
1802 int cmd, inc, i, nslash;
1804 unsigned char val[16];
1806 scanhex((void *)&adrs);
1809 printf(memex_help_string);
1815 while ((cmd = skipbl()) != '\n') {
1817 case 'b': size = 1; break;
1818 case 'w': size = 2; break;
1819 case 'l': size = 4; break;
1820 case 'd': size = 8; break;
1821 case 'r': brev = !brev; break;
1822 case 'n': mnoread = 1; break;
1823 case '.': mnoread = 0; break;
1832 n = mread(adrs, val, size);
1833 printf(REG"%c", adrs, brev? 'r': ' ');
1838 for (i = 0; i < n; ++i)
1839 printf("%.2x", val[i]);
1840 for (; i < size; ++i)
1841 printf("%s", fault_chars[fault_type]);
1848 for (i = 0; i < size; ++i)
1849 val[i] = n >> (i * 8);
1852 mwrite(adrs, val, size);
1865 else if( n == '\'' )
1867 for (i = 0; i < size; ++i)
1868 val[i] = n >> (i * 8);
1871 mwrite(adrs, val, size);
1908 adrs -= 1 << nslash;
1912 adrs += 1 << nslash;
1916 adrs += 1 << -nslash;
1920 adrs -= 1 << -nslash;
1923 scanhex((void *)&adrs);
1942 printf(memex_subcmd_help_string);
1957 case 'n': c = '\n'; break;
1958 case 'r': c = '\r'; break;
1959 case 'b': c = '\b'; break;
1960 case 't': c = '\t'; break;
1965 static void xmon_rawdump (unsigned long adrs, long ndump)
1968 unsigned char temp[16];
1970 for (n = ndump; n > 0;) {
1972 nr = mread(adrs, temp, r);
1974 for (m = 0; m < r; ++m) {
1976 printf("%.2x", temp[m]);
1978 printf("%s", fault_chars[fault_type]);
1987 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
1988 || ('a' <= (c) && (c) <= 'f') \
1989 || ('A' <= (c) && (c) <= 'F'))
1996 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
1998 scanhex((void *)&adrs);
2005 else if (nidump > MAX_DUMP)
2007 adrs += ppc_inst_dump(adrs, nidump, 1);
2009 } else if (c == 'r') {
2013 xmon_rawdump(adrs, ndump);
2020 else if (ndump > MAX_DUMP)
2022 prdump(adrs, ndump);
2029 prdump(unsigned long adrs, long ndump)
2031 long n, m, c, r, nr;
2032 unsigned char temp[16];
2034 for (n = ndump; n > 0;) {
2038 nr = mread(adrs, temp, r);
2040 for (m = 0; m < r; ++m) {
2041 if ((m & (sizeof(long) - 1)) == 0 && m > 0)
2044 printf("%.2x", temp[m]);
2046 printf("%s", fault_chars[fault_type]);
2048 for (; m < 16; ++m) {
2049 if ((m & (sizeof(long) - 1)) == 0)
2054 for (m = 0; m < r; ++m) {
2057 putchar(' ' <= c && c <= '~'? c: '.');
2070 typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr);
2073 generic_inst_dump(unsigned long adr, long count, int praddr,
2074 instruction_dump_func dump_func)
2077 unsigned long first_adr;
2078 unsigned long inst, last_inst = 0;
2079 unsigned char val[4];
2082 for (first_adr = adr; count > 0; --count, adr += 4) {
2083 nr = mread(adr, val, 4);
2086 const char *x = fault_chars[fault_type];
2087 printf(REG" %s%s%s%s\n", adr, x, x, x, x);
2091 inst = GETWORD(val);
2092 if (adr > first_adr && inst == last_inst) {
2102 printf(REG" %.8x", adr, inst);
2104 dump_func(inst, adr);
2107 return adr - first_adr;
2111 ppc_inst_dump(unsigned long adr, long count, int praddr)
2113 return generic_inst_dump(adr, count, praddr, print_insn_powerpc);
2117 print_address(unsigned long addr)
2119 xmon_print_symbol(addr, "\t# ", "");
2124 * Memory operations - move, set, print differences
2126 static unsigned long mdest; /* destination address */
2127 static unsigned long msrc; /* source address */
2128 static unsigned long mval; /* byte value to set memory to */
2129 static unsigned long mcount; /* # bytes to affect */
2130 static unsigned long mdiffs; /* max # differences to print */
2135 scanhex((void *)&mdest);
2136 if( termch != '\n' )
2138 scanhex((void *)(cmd == 's'? &mval: &msrc));
2139 if( termch != '\n' )
2141 scanhex((void *)&mcount);
2144 memmove((void *)mdest, (void *)msrc, mcount);
2147 memset((void *)mdest, mval, mcount);
2150 if( termch != '\n' )
2152 scanhex((void *)&mdiffs);
2153 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2159 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2164 for( n = nb; n > 0; --n )
2165 if( *p1++ != *p2++ )
2166 if( ++prt <= maxpr )
2167 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2168 p1[-1], p2 - 1, p2[-1]);
2170 printf("Total of %d differences\n", prt);
2173 static unsigned mend;
2174 static unsigned mask;
2180 unsigned char val[4];
2183 scanhex((void *)&mdest);
2184 if (termch != '\n') {
2186 scanhex((void *)&mend);
2187 if (termch != '\n') {
2189 scanhex((void *)&mval);
2191 if (termch != '\n') termch = 0;
2192 scanhex((void *)&mask);
2196 for (a = mdest; a < mend; a += 4) {
2197 if (mread(a, val, 4) == 4
2198 && ((GETWORD(val) ^ mval) & mask) == 0) {
2199 printf("%.16x: %.16x\n", a, GETWORD(val));
2206 static unsigned long mskip = 0x1000;
2207 static unsigned long mlim = 0xffffffff;
2217 if (termch != '\n') termch = 0;
2219 if (termch != '\n') termch = 0;
2222 for (a = mdest; a < mlim; a += mskip) {
2223 ok = mread(a, &v, 1);
2225 printf("%.8x .. ", a);
2226 } else if (!ok && ook)
2227 printf("%.8x\n", a - mskip);
2233 printf("%.8x\n", a - mskip);
2238 unsigned long args[8];
2241 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2242 unsigned long, unsigned long, unsigned long,
2243 unsigned long, unsigned long, unsigned long);
2246 if (!scanhex(&adrs))
2250 for (i = 0; i < 8; ++i)
2252 for (i = 0; i < 8; ++i) {
2253 if (!scanhex(&args[i]) || termch == '\n')
2257 func = (callfunc_t) adrs;
2259 if (setjmp(bus_error_jmp) == 0) {
2260 catch_memory_errors = 1;
2262 ret = func(args[0], args[1], args[2], args[3],
2263 args[4], args[5], args[6], args[7]);
2265 printf("return value is %x\n", ret);
2267 printf("*** %x exception occurred\n", fault_except);
2269 catch_memory_errors = 0;
2272 /* Input scanning routines */
2283 while( c == ' ' || c == '\t' )
2289 static char *regnames[N_PTREGS] = {
2290 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2291 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2292 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2293 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2294 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2300 "trap", "dar", "dsisr", "res"
2304 scanhex(unsigned long *vp)
2311 /* parse register name */
2315 for (i = 0; i < sizeof(regname) - 1; ++i) {
2324 for (i = 0; i < N_PTREGS; ++i) {
2325 if (strcmp(regnames[i], regname) == 0) {
2326 if (xmon_regs == NULL) {
2327 printf("regs not available\n");
2330 *vp = ((unsigned long *)xmon_regs)[i];
2334 printf("invalid register name '%%%s'\n", regname);
2338 /* skip leading "0x" if any */
2352 } else if (c == '$') {
2354 for (i=0; i<63; i++) {
2364 if (setjmp(bus_error_jmp) == 0) {
2365 catch_memory_errors = 1;
2367 *vp = kallsyms_lookup_name(tmpstr);
2370 catch_memory_errors = 0;
2372 printf("unknown symbol '%s'\n", tmpstr);
2407 if( '0' <= c && c <= '9' )
2409 if( 'A' <= c && c <= 'F' )
2410 return c - ('A' - 10);
2411 if( 'a' <= c && c <= 'f' )
2412 return c - ('a' - 10);
2417 getstring(char *s, int size)
2428 } while( c != ' ' && c != '\t' && c != '\n' );
2433 static char line[256];
2434 static char *lineptr;
2445 if (lineptr == NULL || *lineptr == 0) {
2446 if (xmon_gets(line, sizeof(line)) == NULL) {
2456 take_input(char *str)
2465 int type = inchar();
2467 static char tmp[64];
2472 xmon_print_symbol(addr, ": ", "\n");
2477 if (setjmp(bus_error_jmp) == 0) {
2478 catch_memory_errors = 1;
2480 addr = kallsyms_lookup_name(tmp);
2482 printf("%s: %lx\n", tmp, addr);
2484 printf("Symbol '%s' not found.\n", tmp);
2487 catch_memory_errors = 0;
2494 /* Print an address in numeric and symbolic form (if possible) */
2495 static void xmon_print_symbol(unsigned long address, const char *mid,
2499 const char *name = NULL;
2500 unsigned long offset, size;
2502 printf(REG, address);
2503 if (setjmp(bus_error_jmp) == 0) {
2504 catch_memory_errors = 1;
2506 name = kallsyms_lookup(address, &size, &offset, &modname,
2509 /* wait a little while to see if we get a machine check */
2513 catch_memory_errors = 0;
2516 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2518 printf(" [%s]", modname);
2520 printf("%s", after);
2524 static void dump_slb(void)
2527 unsigned long esid,vsid,valid;
2530 printf("SLB contents of cpu %x\n", smp_processor_id());
2532 for (i = 0; i < mmu_slb_size; i++) {
2533 asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i));
2534 asm volatile("slbmfev %0,%1" : "=r" (vsid) : "r" (i));
2535 valid = (esid & SLB_ESID_V);
2536 if (valid | esid | vsid) {
2537 printf("%02d %016lx %016lx", i, esid, vsid);
2539 llp = vsid & SLB_VSID_LLP;
2540 if (vsid & SLB_VSID_B_1T) {
2541 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
2543 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T,
2546 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
2548 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT,
2557 static void dump_stab(void)
2560 unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2562 printf("Segment table contents of cpu %x\n", smp_processor_id());
2564 for (i = 0; i < PAGE_SIZE/16; i++) {
2571 printf("%03d %016lx ", i, a);
2572 printf("%016lx\n", b);
2577 void dump_segments(void)
2579 if (cpu_has_feature(CPU_FTR_SLB))
2586 #ifdef CONFIG_PPC_STD_MMU_32
2587 void dump_segments(void)
2592 for (i = 0; i < 16; ++i)
2593 printf(" %x", mfsrin(i));
2599 static void dump_tlb_44x(void)
2603 for (i = 0; i < PPC44x_TLB_SIZE; i++) {
2604 unsigned long w0,w1,w2;
2605 asm volatile("tlbre %0,%1,0" : "=r" (w0) : "r" (i));
2606 asm volatile("tlbre %0,%1,1" : "=r" (w1) : "r" (i));
2607 asm volatile("tlbre %0,%1,2" : "=r" (w2) : "r" (i));
2608 printf("[%02x] %08x %08x %08x ", i, w0, w1, w2);
2609 if (w0 & PPC44x_TLB_VALID) {
2610 printf("V %08x -> %01x%08x %c%c%c%c%c",
2611 w0 & PPC44x_TLB_EPN_MASK,
2612 w1 & PPC44x_TLB_ERPN_MASK,
2613 w1 & PPC44x_TLB_RPN_MASK,
2614 (w2 & PPC44x_TLB_W) ? 'W' : 'w',
2615 (w2 & PPC44x_TLB_I) ? 'I' : 'i',
2616 (w2 & PPC44x_TLB_M) ? 'M' : 'm',
2617 (w2 & PPC44x_TLB_G) ? 'G' : 'g',
2618 (w2 & PPC44x_TLB_E) ? 'E' : 'e');
2623 #endif /* CONFIG_44x */
2624 void xmon_init(int enable)
2626 #ifdef CONFIG_PPC_ISERIES
2627 if (firmware_has_feature(FW_FEATURE_ISERIES))
2632 __debugger_ipi = xmon_ipi;
2633 __debugger_bpt = xmon_bpt;
2634 __debugger_sstep = xmon_sstep;
2635 __debugger_iabr_match = xmon_iabr_match;
2636 __debugger_dabr_match = xmon_dabr_match;
2637 __debugger_fault_handler = xmon_fault_handler;
2640 __debugger_ipi = NULL;
2641 __debugger_bpt = NULL;
2642 __debugger_sstep = NULL;
2643 __debugger_iabr_match = NULL;
2644 __debugger_dabr_match = NULL;
2645 __debugger_fault_handler = NULL;
2650 #ifdef CONFIG_MAGIC_SYSRQ
2651 static void sysrq_handle_xmon(int key, struct tty_struct *tty)
2653 /* ensure xmon is enabled */
2655 debugger(get_irq_regs());
2658 static struct sysrq_key_op sysrq_xmon_op =
2660 .handler = sysrq_handle_xmon,
2662 .action_msg = "Entering xmon",
2665 static int __init setup_xmon_sysrq(void)
2667 #ifdef CONFIG_PPC_ISERIES
2668 if (firmware_has_feature(FW_FEATURE_ISERIES))
2671 register_sysrq_key('x', &sysrq_xmon_op);
2674 __initcall(setup_xmon_sysrq);
2675 #endif /* CONFIG_MAGIC_SYSRQ */
2677 static int __initdata xmon_early, xmon_off;
2679 static int __init early_parse_xmon(char *p)
2681 if (!p || strncmp(p, "early", 5) == 0) {
2682 /* just "xmon" is equivalent to "xmon=early" */
2685 } else if (strncmp(p, "on", 2) == 0)
2687 else if (strncmp(p, "off", 3) == 0)
2689 else if (strncmp(p, "nobt", 4) == 0)
2690 xmon_no_auto_backtrace = 1;
2696 early_param("xmon", early_parse_xmon);
2698 void __init xmon_setup(void)
2700 #ifdef CONFIG_XMON_DEFAULT
2708 #ifdef CONFIG_SPU_BASE
2712 u64 saved_mfc_sr1_RW;
2713 u32 saved_spu_runcntl_RW;
2714 unsigned long dump_addr;
2718 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
2720 static struct spu_info spu_info[XMON_NUM_SPUS];
2722 void xmon_register_spus(struct list_head *list)
2726 list_for_each_entry(spu, list, full_list) {
2727 if (spu->number >= XMON_NUM_SPUS) {
2732 spu_info[spu->number].spu = spu;
2733 spu_info[spu->number].stopped_ok = 0;
2734 spu_info[spu->number].dump_addr = (unsigned long)
2735 spu_info[spu->number].spu->local_store;
2739 static void stop_spus(void)
2745 for (i = 0; i < XMON_NUM_SPUS; i++) {
2746 if (!spu_info[i].spu)
2749 if (setjmp(bus_error_jmp) == 0) {
2750 catch_memory_errors = 1;
2753 spu = spu_info[i].spu;
2755 spu_info[i].saved_spu_runcntl_RW =
2756 in_be32(&spu->problem->spu_runcntl_RW);
2758 tmp = spu_mfc_sr1_get(spu);
2759 spu_info[i].saved_mfc_sr1_RW = tmp;
2761 tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
2762 spu_mfc_sr1_set(spu, tmp);
2767 spu_info[i].stopped_ok = 1;
2769 printf("Stopped spu %.2d (was %s)\n", i,
2770 spu_info[i].saved_spu_runcntl_RW ?
2771 "running" : "stopped");
2773 catch_memory_errors = 0;
2774 printf("*** Error stopping spu %.2d\n", i);
2776 catch_memory_errors = 0;
2780 static void restart_spus(void)
2785 for (i = 0; i < XMON_NUM_SPUS; i++) {
2786 if (!spu_info[i].spu)
2789 if (!spu_info[i].stopped_ok) {
2790 printf("*** Error, spu %d was not successfully stopped"
2791 ", not restarting\n", i);
2795 if (setjmp(bus_error_jmp) == 0) {
2796 catch_memory_errors = 1;
2799 spu = spu_info[i].spu;
2800 spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
2801 out_be32(&spu->problem->spu_runcntl_RW,
2802 spu_info[i].saved_spu_runcntl_RW);
2807 printf("Restarted spu %.2d\n", i);
2809 catch_memory_errors = 0;
2810 printf("*** Error restarting spu %.2d\n", i);
2812 catch_memory_errors = 0;
2816 #define DUMP_WIDTH 23
2817 #define DUMP_VALUE(format, field, value) \
2819 if (setjmp(bus_error_jmp) == 0) { \
2820 catch_memory_errors = 1; \
2822 printf(" %-*s = "format"\n", DUMP_WIDTH, \
2827 catch_memory_errors = 0; \
2828 printf(" %-*s = *** Error reading field.\n", \
2829 DUMP_WIDTH, #field); \
2831 catch_memory_errors = 0; \
2834 #define DUMP_FIELD(obj, format, field) \
2835 DUMP_VALUE(format, field, obj->field)
2837 static void dump_spu_fields(struct spu *spu)
2839 printf("Dumping spu fields at address %p:\n", spu);
2841 DUMP_FIELD(spu, "0x%x", number);
2842 DUMP_FIELD(spu, "%s", name);
2843 DUMP_FIELD(spu, "0x%lx", local_store_phys);
2844 DUMP_FIELD(spu, "0x%p", local_store);
2845 DUMP_FIELD(spu, "0x%lx", ls_size);
2846 DUMP_FIELD(spu, "0x%x", node);
2847 DUMP_FIELD(spu, "0x%lx", flags);
2848 DUMP_FIELD(spu, "0x%lx", dar);
2849 DUMP_FIELD(spu, "0x%lx", dsisr);
2850 DUMP_FIELD(spu, "%d", class_0_pending);
2851 DUMP_FIELD(spu, "0x%lx", irqs[0]);
2852 DUMP_FIELD(spu, "0x%lx", irqs[1]);
2853 DUMP_FIELD(spu, "0x%lx", irqs[2]);
2854 DUMP_FIELD(spu, "0x%x", slb_replace);
2855 DUMP_FIELD(spu, "%d", pid);
2856 DUMP_FIELD(spu, "0x%p", mm);
2857 DUMP_FIELD(spu, "0x%p", ctx);
2858 DUMP_FIELD(spu, "0x%p", rq);
2859 DUMP_FIELD(spu, "0x%p", timestamp);
2860 DUMP_FIELD(spu, "0x%lx", problem_phys);
2861 DUMP_FIELD(spu, "0x%p", problem);
2862 DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
2863 in_be32(&spu->problem->spu_runcntl_RW));
2864 DUMP_VALUE("0x%x", problem->spu_status_R,
2865 in_be32(&spu->problem->spu_status_R));
2866 DUMP_VALUE("0x%x", problem->spu_npc_RW,
2867 in_be32(&spu->problem->spu_npc_RW));
2868 DUMP_FIELD(spu, "0x%p", priv2);
2869 DUMP_FIELD(spu, "0x%p", pdata);
2873 spu_inst_dump(unsigned long adr, long count, int praddr)
2875 return generic_inst_dump(adr, count, praddr, print_insn_spu);
2878 static void dump_spu_ls(unsigned long num, int subcmd)
2880 unsigned long offset, addr, ls_addr;
2882 if (setjmp(bus_error_jmp) == 0) {
2883 catch_memory_errors = 1;
2885 ls_addr = (unsigned long)spu_info[num].spu->local_store;
2889 catch_memory_errors = 0;
2890 printf("*** Error: accessing spu info for spu %d\n", num);
2893 catch_memory_errors = 0;
2895 if (scanhex(&offset))
2896 addr = ls_addr + offset;
2898 addr = spu_info[num].dump_addr;
2900 if (addr >= ls_addr + LS_SIZE) {
2901 printf("*** Error: address outside of local store\n");
2907 addr += spu_inst_dump(addr, 16, 1);
2917 spu_info[num].dump_addr = addr;
2920 static int do_spu_cmd(void)
2922 static unsigned long num = 0;
2923 int cmd, subcmd = 0;
2935 if (isxdigit(subcmd) || subcmd == '\n')
2939 if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
2940 printf("*** Error: invalid spu number\n");
2946 dump_spu_fields(spu_info[num].spu);
2949 dump_spu_ls(num, subcmd);
2960 #else /* ! CONFIG_SPU_BASE */
2961 static int do_spu_cmd(void)