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>
26 #include <asm/ptrace.h>
27 #include <asm/string.h>
29 #include <asm/machdep.h>
31 #include <asm/processor.h>
32 #include <asm/pgtable.h>
34 #include <asm/mmu_context.h>
35 #include <asm/cputable.h>
37 #include <asm/sstep.h>
39 #include <asm/irq_regs.h>
41 #include <asm/spu_priv1.h>
42 #include <asm/firmware.h>
45 #include <asm/hvcall.h>
51 #define scanhex xmon_scanhex
52 #define skipbl xmon_skipbl
55 cpumask_t cpus_in_xmon = CPU_MASK_NONE;
56 static unsigned long xmon_taken = 1;
57 static int xmon_owner;
59 #endif /* CONFIG_SMP */
61 static unsigned long in_xmon = 0;
63 static unsigned long adrs;
65 #define MAX_DUMP (128 * 1024)
66 static unsigned long ndump = 64;
67 static unsigned long nidump = 16;
68 static unsigned long ncsum = 4096;
70 static char tmpstr[128];
72 #define JMP_BUF_LEN 23
73 static long bus_error_jmp[JMP_BUF_LEN];
74 static int catch_memory_errors;
75 static long *xmon_fault_jmp[NR_CPUS];
76 #define setjmp xmon_setjmp
77 #define longjmp xmon_longjmp
79 /* Breakpoint stuff */
81 unsigned long address;
82 unsigned int instr[2];
88 /* Bits in bpt.enabled */
89 #define BP_IABR_TE 1 /* IABR translation enabled */
95 static struct bpt bpts[NBPTS];
96 static struct bpt dabr;
97 static struct bpt *iabr;
98 static unsigned bpinstr = 0x7fe00008; /* trap */
100 #define BP_NUM(bp) ((bp) - bpts + 1)
103 static int cmds(struct pt_regs *);
104 static int mread(unsigned long, void *, int);
105 static int mwrite(unsigned long, void *, int);
106 static int handle_fault(struct pt_regs *);
107 static void byterev(unsigned char *, int);
108 static void memex(void);
109 static int bsesc(void);
110 static void dump(void);
111 static void prdump(unsigned long, long);
112 static int ppc_inst_dump(unsigned long, long, int);
113 void print_address(unsigned long);
114 static void backtrace(struct pt_regs *);
115 static void excprint(struct pt_regs *);
116 static void prregs(struct pt_regs *);
117 static void memops(int);
118 static void memlocate(void);
119 static void memzcan(void);
120 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
122 int scanhex(unsigned long *valp);
123 static void scannl(void);
124 static int hexdigit(int);
125 void getstring(char *, int);
126 static void flush_input(void);
127 static int inchar(void);
128 static void take_input(char *);
129 static unsigned long read_spr(int);
130 static void write_spr(int, unsigned long);
131 static void super_regs(void);
132 static void remove_bpts(void);
133 static void insert_bpts(void);
134 static void remove_cpu_bpts(void);
135 static void insert_cpu_bpts(void);
136 static struct bpt *at_breakpoint(unsigned long pc);
137 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
138 static int do_step(struct pt_regs *);
139 static void bpt_cmds(void);
140 static void cacheflush(void);
141 static int cpu_cmd(void);
142 static void csum(void);
143 static void bootcmds(void);
144 static void proccall(void);
145 void dump_segments(void);
146 static void symbol_lookup(void);
147 static void xmon_show_stack(unsigned long sp, unsigned long lr,
149 static void xmon_print_symbol(unsigned long address, const char *mid,
151 static const char *getvecname(unsigned long vec);
153 static int do_spu_cmd(void);
155 int xmon_no_auto_backtrace;
157 extern int print_insn_powerpc(unsigned long insn, unsigned long memaddr);
158 extern int print_insn_spu(unsigned long insn, unsigned long memaddr);
160 extern void xmon_enter(void);
161 extern void xmon_leave(void);
163 extern long setjmp(long *);
164 extern void longjmp(long *, long);
165 extern void xmon_save_regs(struct pt_regs *);
169 #define REGS_PER_LINE 4
170 #define LAST_VOLATILE 13
173 #define REGS_PER_LINE 8
174 #define LAST_VOLATILE 12
177 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
179 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
180 || ('a' <= (c) && (c) <= 'f') \
181 || ('A' <= (c) && (c) <= 'F'))
182 #define isalnum(c) (('0' <= (c) && (c) <= '9') \
183 || ('a' <= (c) && (c) <= 'z') \
184 || ('A' <= (c) && (c) <= 'Z'))
185 #define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
187 static char *help_string = "\
189 b show breakpoints\n\
190 bd set data breakpoint\n\
191 bi set instruction breakpoint\n\
192 bc clear breakpoint\n"
195 c print cpus stopped in xmon\n\
196 c# try to switch to cpu number h (in hex)\n"
201 di dump instructions\n\
202 df dump float values\n\
203 dd dump double values\n\
204 dr dump stream of raw bytes\n\
205 e print exception information\n\
207 la lookup symbol+offset of specified address\n\
208 ls lookup address of specified symbol\n\
209 m examine/change memory\n\
210 mm move a block of memory\n\
211 ms set a block of memory\n\
212 md compare two blocks of memory\n\
213 ml locate a block of memory\n\
214 mz zero a block of memory\n\
215 mi show information about memory allocation\n\
216 p call a procedure\n\
219 #ifdef CONFIG_PPC_CELL
220 " ss stop execution on all spus\n\
221 sr restore execution on stopped spus\n\
222 sf # dump spu fields for spu # (in hex)\n\
223 sd # dump spu local store for spu # (in hex)\
224 sdi # disassemble spu local store for spu # (in hex)\n"
226 " S print special registers\n\
228 x exit monitor and recover\n\
229 X exit monitor and dont recover\n"
231 " u dump segment table or SLB\n"
233 #ifdef CONFIG_PPC_STD_MMU_32
234 " 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)
337 long recurse_jmp[JMP_BUF_LEN];
338 unsigned long offset;
342 unsigned long timeout;
346 mtmsr(msr & ~MSR_EE); /* disable interrupts */
348 bp = in_breakpoint_table(regs->nip, &offset);
350 regs->nip = bp->address + offset;
351 atomic_dec(&bp->ref_count);
357 cpu = smp_processor_id();
358 if (cpu_isset(cpu, cpus_in_xmon)) {
361 printf("cpu 0x%x: Exception %lx %s in xmon, "
362 "returning to main loop\n",
363 cpu, regs->trap, getvecname(TRAP(regs)));
364 release_output_lock();
365 longjmp(xmon_fault_jmp[cpu], 1);
368 if (setjmp(recurse_jmp) != 0) {
369 if (!in_xmon || !xmon_gate) {
371 printf("xmon: WARNING: bad recursive fault "
372 "on cpu 0x%x\n", cpu);
373 release_output_lock();
376 secondary = !(xmon_taken && cpu == xmon_owner);
380 xmon_fault_jmp[cpu] = recurse_jmp;
381 cpu_set(cpu, cpus_in_xmon);
384 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
385 bp = at_breakpoint(regs->nip);
386 if (bp || (regs->msr & MSR_RI) == 0)
393 printf("cpu 0x%x stopped at breakpoint 0x%x (",
395 xmon_print_symbol(regs->nip, " ", ")\n");
397 if ((regs->msr & MSR_RI) == 0)
398 printf("WARNING: exception is not recoverable, "
400 release_output_lock();
405 while (secondary && !xmon_gate) {
409 secondary = test_and_set_bit(0, &in_xmon);
414 if (!secondary && !xmon_gate) {
415 /* we are the first cpu to come in */
416 /* interrupt other cpu(s) */
417 int ncpus = num_online_cpus();
422 smp_send_debugger_break(MSG_ALL_BUT_SELF);
423 /* wait for other cpus to come in */
424 for (timeout = 100000000; timeout != 0; --timeout) {
425 if (cpus_weight(cpus_in_xmon) >= ncpus)
431 disable_surveillance();
432 /* for breakpoint or single step, print the current instr. */
433 if (bp || TRAP(regs) == 0xd00)
434 ppc_inst_dump(regs->nip, 1, 0);
435 printf("enter ? for help\n");
444 if (cpu == xmon_owner) {
445 if (!test_and_set_bit(0, &xmon_taken)) {
450 while (cpu == xmon_owner)
464 /* have switched to some other cpu */
469 cpu_clear(cpu, cpus_in_xmon);
470 xmon_fault_jmp[cpu] = NULL;
472 /* UP is simple... */
474 printf("Exception %lx %s in xmon, returning to main loop\n",
475 regs->trap, getvecname(TRAP(regs)));
476 longjmp(xmon_fault_jmp[0], 1);
478 if (setjmp(recurse_jmp) == 0) {
479 xmon_fault_jmp[0] = recurse_jmp;
483 bp = at_breakpoint(regs->nip);
485 printf("Stopped at breakpoint %x (", BP_NUM(bp));
486 xmon_print_symbol(regs->nip, " ", ")\n");
488 if ((regs->msr & MSR_RI) == 0)
489 printf("WARNING: exception is not recoverable, "
492 disable_surveillance();
493 /* for breakpoint or single step, print the current instr. */
494 if (bp || TRAP(regs) == 0xd00)
495 ppc_inst_dump(regs->nip, 1, 0);
496 printf("enter ? for help\n");
505 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
506 bp = at_breakpoint(regs->nip);
508 int stepped = emulate_step(regs, bp->instr[0]);
510 regs->nip = (unsigned long) &bp->instr[0];
511 atomic_inc(&bp->ref_count);
512 } else if (stepped < 0) {
513 printf("Couldn't single-step %s instruction\n",
514 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
521 mtmsr(msr); /* restore interrupt enable */
523 return cmd != 'X' && cmd != EOF;
526 int xmon(struct pt_regs *excp)
531 xmon_save_regs(®s);
535 return xmon_core(excp, 0);
539 irqreturn_t xmon_irq(int irq, void *d)
542 local_irq_save(flags);
543 printf("Keyboard interrupt\n");
544 xmon(get_irq_regs());
545 local_irq_restore(flags);
549 static int xmon_bpt(struct pt_regs *regs)
552 unsigned long offset;
554 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
557 /* Are we at the trap at bp->instr[1] for some bp? */
558 bp = in_breakpoint_table(regs->nip, &offset);
559 if (bp != NULL && offset == 4) {
560 regs->nip = bp->address + 4;
561 atomic_dec(&bp->ref_count);
565 /* Are we at a breakpoint? */
566 bp = at_breakpoint(regs->nip);
575 static int xmon_sstep(struct pt_regs *regs)
583 static int xmon_dabr_match(struct pt_regs *regs)
585 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
587 if (dabr.enabled == 0)
593 static int xmon_iabr_match(struct pt_regs *regs)
595 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
603 static int xmon_ipi(struct pt_regs *regs)
606 if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
612 static int xmon_fault_handler(struct pt_regs *regs)
615 unsigned long offset;
617 if (in_xmon && catch_memory_errors)
618 handle_fault(regs); /* doesn't return */
620 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
621 bp = in_breakpoint_table(regs->nip, &offset);
623 regs->nip = bp->address + offset;
624 atomic_dec(&bp->ref_count);
631 static struct bpt *at_breakpoint(unsigned long pc)
637 for (i = 0; i < NBPTS; ++i, ++bp)
638 if (bp->enabled && pc == bp->address)
643 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
647 off = nip - (unsigned long) bpts;
648 if (off >= sizeof(bpts))
650 off %= sizeof(struct bpt);
651 if (off != offsetof(struct bpt, instr[0])
652 && off != offsetof(struct bpt, instr[1]))
654 *offp = off - offsetof(struct bpt, instr[0]);
655 return (struct bpt *) (nip - off);
658 static struct bpt *new_breakpoint(unsigned long a)
663 bp = at_breakpoint(a);
667 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
668 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
670 bp->instr[1] = bpinstr;
671 store_inst(&bp->instr[1]);
676 printf("Sorry, no free breakpoints. Please clear one first.\n");
680 static void insert_bpts(void)
686 for (i = 0; i < NBPTS; ++i, ++bp) {
687 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
689 if (mread(bp->address, &bp->instr[0], 4) != 4) {
690 printf("Couldn't read instruction at %lx, "
691 "disabling breakpoint there\n", bp->address);
695 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
696 printf("Breakpoint at %lx is on an mtmsrd or rfid "
697 "instruction, disabling it\n", bp->address);
701 store_inst(&bp->instr[0]);
702 if (bp->enabled & BP_IABR)
704 if (mwrite(bp->address, &bpinstr, 4) != 4) {
705 printf("Couldn't write instruction at %lx, "
706 "disabling breakpoint there\n", bp->address);
707 bp->enabled &= ~BP_TRAP;
710 store_inst((void *)bp->address);
714 static void insert_cpu_bpts(void)
717 set_dabr(dabr.address | (dabr.enabled & 7));
718 if (iabr && cpu_has_feature(CPU_FTR_IABR))
719 mtspr(SPRN_IABR, iabr->address
720 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
723 static void remove_bpts(void)
730 for (i = 0; i < NBPTS; ++i, ++bp) {
731 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
733 if (mread(bp->address, &instr, 4) == 4
735 && mwrite(bp->address, &bp->instr, 4) != 4)
736 printf("Couldn't remove breakpoint at %lx\n",
739 store_inst((void *)bp->address);
743 static void remove_cpu_bpts(void)
746 if (cpu_has_feature(CPU_FTR_IABR))
750 /* Command interpreting routine */
751 static char *last_cmd;
754 cmds(struct pt_regs *excp)
761 if (!xmon_no_auto_backtrace) {
762 xmon_no_auto_backtrace = 1;
763 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
768 printf("%x:", smp_processor_id());
769 #endif /* CONFIG_SMP */
775 if (last_cmd == NULL)
777 take_input(last_cmd);
811 prregs(excp); /* print regs */
826 if (do_spu_cmd() == 0)
835 printf(" <no input ...>\n");
857 #ifdef CONFIG_PPC_STD_MMU
863 printf("Unrecognized command: ");
865 if (' ' < cmd && cmd <= '~')
868 printf("\\x%x", cmd);
870 } while (cmd != '\n');
871 printf(" (type ? for help)\n");
878 * Step a single instruction.
879 * Some instructions we emulate, others we execute with MSR_SE set.
881 static int do_step(struct pt_regs *regs)
886 /* check we are in 64-bit kernel mode, translation enabled */
887 if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
888 if (mread(regs->nip, &instr, 4) == 4) {
889 stepped = emulate_step(regs, instr);
891 printf("Couldn't single-step %s instruction\n",
892 (IS_RFID(instr)? "rfid": "mtmsrd"));
896 regs->trap = 0xd00 | (regs->trap & 1);
897 printf("stepped to ");
898 xmon_print_symbol(regs->nip, " ", "\n");
899 ppc_inst_dump(regs->nip, 1, 0);
908 static void bootcmds(void)
914 ppc_md.restart(NULL);
921 static int cpu_cmd(void)
928 if (!scanhex(&cpu)) {
929 /* print cpus waiting or in xmon */
930 printf("cpus stopped:");
932 for (cpu = 0; cpu < NR_CPUS; ++cpu) {
933 if (cpu_isset(cpu, cpus_in_xmon)) {
939 printf("-%x", cpu - 1);
944 printf("-%x", NR_CPUS - 1);
948 /* try to switch to cpu specified */
949 if (!cpu_isset(cpu, cpus_in_xmon)) {
950 printf("cpu 0x%x isn't in xmon\n", cpu);
957 while (!xmon_taken) {
958 if (--timeout == 0) {
959 if (test_and_set_bit(0, &xmon_taken))
961 /* take control back */
963 xmon_owner = smp_processor_id();
964 printf("cpu %u didn't take control\n", cpu);
972 #endif /* CONFIG_SMP */
975 static unsigned short fcstab[256] = {
976 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
977 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
978 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
979 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
980 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
981 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
982 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
983 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
984 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
985 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
986 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
987 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
988 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
989 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
990 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
991 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
992 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
993 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
994 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
995 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
996 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
997 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
998 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
999 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1000 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1001 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1002 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1003 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1004 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1005 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1006 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1007 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1010 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1019 if (!scanhex(&adrs))
1021 if (!scanhex(&ncsum))
1024 for (i = 0; i < ncsum; ++i) {
1025 if (mread(adrs+i, &v, 1) == 0) {
1026 printf("csum stopped at %x\n", adrs+i);
1031 printf("%x\n", fcs);
1035 * Check if this is a suitable place to put a breakpoint.
1037 static long check_bp_loc(unsigned long addr)
1042 if (!is_kernel_addr(addr)) {
1043 printf("Breakpoints may only be placed at kernel addresses\n");
1046 if (!mread(addr, &instr, sizeof(instr))) {
1047 printf("Can't read instruction at address %lx\n", addr);
1050 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1051 printf("Breakpoints may not be placed on mtmsrd or rfid "
1058 static char *breakpoint_help_string =
1059 "Breakpoint command usage:\n"
1060 "b show breakpoints\n"
1061 "b <addr> [cnt] set breakpoint at given instr addr\n"
1062 "bc clear all breakpoints\n"
1063 "bc <n/addr> clear breakpoint number n or at addr\n"
1064 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1065 "bd <addr> [cnt] set hardware data breakpoint\n"
1075 const char badaddr[] = "Only kernel addresses are permitted "
1076 "for breakpoints\n";
1081 case 'd': /* bd - hardware data breakpoint */
1086 else if (cmd == 'w')
1092 if (scanhex(&dabr.address)) {
1093 if (!is_kernel_addr(dabr.address)) {
1098 dabr.enabled = mode | BP_DABR;
1102 case 'i': /* bi - hardware instr breakpoint */
1103 if (!cpu_has_feature(CPU_FTR_IABR)) {
1104 printf("Hardware instruction breakpoint "
1105 "not supported on this cpu\n");
1109 iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1114 if (!check_bp_loc(a))
1116 bp = new_breakpoint(a);
1118 bp->enabled |= BP_IABR | BP_IABR_TE;
1126 /* clear all breakpoints */
1127 for (i = 0; i < NBPTS; ++i)
1128 bpts[i].enabled = 0;
1131 printf("All breakpoints cleared\n");
1135 if (a <= NBPTS && a >= 1) {
1136 /* assume a breakpoint number */
1137 bp = &bpts[a-1]; /* bp nums are 1 based */
1139 /* assume a breakpoint address */
1140 bp = at_breakpoint(a);
1142 printf("No breakpoint at %x\n", a);
1147 printf("Cleared breakpoint %x (", BP_NUM(bp));
1148 xmon_print_symbol(bp->address, " ", ")\n");
1156 printf(breakpoint_help_string);
1161 /* print all breakpoints */
1162 printf(" type address\n");
1164 printf(" data "REG" [", dabr.address);
1165 if (dabr.enabled & 1)
1167 if (dabr.enabled & 2)
1171 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1174 printf("%2x %s ", BP_NUM(bp),
1175 (bp->enabled & BP_IABR)? "inst": "trap");
1176 xmon_print_symbol(bp->address, " ", "\n");
1181 if (!check_bp_loc(a))
1183 bp = new_breakpoint(a);
1185 bp->enabled |= BP_TRAP;
1190 /* Very cheap human name for vector lookup. */
1192 const char *getvecname(unsigned long vec)
1197 case 0x100: ret = "(System Reset)"; break;
1198 case 0x200: ret = "(Machine Check)"; break;
1199 case 0x300: ret = "(Data Access)"; break;
1200 case 0x380: ret = "(Data SLB Access)"; break;
1201 case 0x400: ret = "(Instruction Access)"; break;
1202 case 0x480: ret = "(Instruction SLB Access)"; break;
1203 case 0x500: ret = "(Hardware Interrupt)"; break;
1204 case 0x600: ret = "(Alignment)"; break;
1205 case 0x700: ret = "(Program Check)"; break;
1206 case 0x800: ret = "(FPU Unavailable)"; break;
1207 case 0x900: ret = "(Decrementer)"; break;
1208 case 0xc00: ret = "(System Call)"; break;
1209 case 0xd00: ret = "(Single Step)"; break;
1210 case 0xf00: ret = "(Performance Monitor)"; break;
1211 case 0xf20: ret = "(Altivec Unavailable)"; break;
1212 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1218 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1219 unsigned long *endp)
1221 unsigned long size, offset;
1225 *startp = *endp = 0;
1228 if (setjmp(bus_error_jmp) == 0) {
1229 catch_memory_errors = 1;
1231 name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr);
1233 *startp = pc - offset;
1234 *endp = pc - offset + size;
1238 catch_memory_errors = 0;
1241 static int xmon_depth_to_print = 64;
1244 #define LRSAVE_OFFSET 0x10
1245 #define REG_FRAME_MARKER 0x7265677368657265ul /* "regshere" */
1246 #define MARKER_OFFSET 0x60
1247 #define REGS_OFFSET 0x70
1249 #define LRSAVE_OFFSET 4
1250 #define REG_FRAME_MARKER 0x72656773
1251 #define MARKER_OFFSET 8
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 == REG_FRAME_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 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 (bug->line & BUG_WARNING_TRAP)
1365 printf("kernel BUG in %s at %s:%d!\n",
1366 bug->function, bug->file, (unsigned int)bug->line);
1369 void excprint(struct pt_regs *fp)
1374 printf("cpu 0x%x: ", smp_processor_id());
1375 #endif /* CONFIG_SMP */
1378 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1380 xmon_print_symbol(fp->nip, ": ", "\n");
1382 printf(" lr: ", fp->link);
1383 xmon_print_symbol(fp->link, ": ", "\n");
1385 printf(" sp: %lx\n", fp->gpr[1]);
1386 printf(" msr: %lx\n", fp->msr);
1388 if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1389 printf(" dar: %lx\n", fp->dar);
1391 printf(" dsisr: %lx\n", fp->dsisr);
1394 printf(" current = 0x%lx\n", current);
1396 printf(" paca = 0x%lx\n", get_paca());
1399 printf(" pid = %ld, comm = %s\n",
1400 current->pid, current->comm);
1407 void prregs(struct pt_regs *fp)
1411 struct pt_regs regs;
1413 if (scanhex(&base)) {
1414 if (setjmp(bus_error_jmp) == 0) {
1415 catch_memory_errors = 1;
1417 regs = *(struct pt_regs *)base;
1421 catch_memory_errors = 0;
1422 printf("*** Error reading registers from "REG"\n",
1426 catch_memory_errors = 0;
1431 if (FULL_REGS(fp)) {
1432 for (n = 0; n < 16; ++n)
1433 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1434 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1436 for (n = 0; n < 7; ++n)
1437 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1438 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1441 for (n = 0; n < 32; ++n) {
1442 printf("R%.2d = %.8x%s", n, fp->gpr[n],
1443 (n & 3) == 3? "\n": " ");
1444 if (n == 12 && !FULL_REGS(fp)) {
1451 xmon_print_symbol(fp->nip, " ", "\n");
1453 xmon_print_symbol(fp->link, " ", "\n");
1454 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
1455 printf("ctr = "REG" xer = "REG" trap = %4lx\n",
1456 fp->ctr, fp->xer, fp->trap);
1458 if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1459 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1462 void cacheflush(void)
1465 unsigned long nflush;
1470 scanhex((void *)&adrs);
1475 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1476 if (setjmp(bus_error_jmp) == 0) {
1477 catch_memory_errors = 1;
1481 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1482 cflush((void *) adrs);
1484 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1485 cinval((void *) adrs);
1488 /* wait a little while to see if we get a machine check */
1491 catch_memory_errors = 0;
1497 unsigned int instrs[2];
1498 unsigned long (*code)(void);
1499 unsigned long ret = -1UL;
1501 unsigned long opd[3];
1503 opd[0] = (unsigned long)instrs;
1506 code = (unsigned long (*)(void)) opd;
1508 code = (unsigned long (*)(void)) instrs;
1511 /* mfspr r3,n; blr */
1512 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1513 instrs[1] = 0x4e800020;
1515 store_inst(instrs+1);
1517 if (setjmp(bus_error_jmp) == 0) {
1518 catch_memory_errors = 1;
1524 /* wait a little while to see if we get a machine check */
1533 write_spr(int n, unsigned long val)
1535 unsigned int instrs[2];
1536 unsigned long (*code)(unsigned long);
1538 unsigned long opd[3];
1540 opd[0] = (unsigned long)instrs;
1543 code = (unsigned long (*)(unsigned long)) opd;
1545 code = (unsigned long (*)(unsigned long)) instrs;
1548 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1549 instrs[1] = 0x4e800020;
1551 store_inst(instrs+1);
1553 if (setjmp(bus_error_jmp) == 0) {
1554 catch_memory_errors = 1;
1560 /* wait a little while to see if we get a machine check */
1566 static unsigned long regno;
1567 extern char exc_prolog;
1568 extern char dec_exc;
1570 void super_regs(void)
1577 unsigned long sp, toc;
1578 asm("mr %0,1" : "=r" (sp) :);
1579 asm("mr %0,2" : "=r" (toc) :);
1581 printf("msr = "REG" sprg0= "REG"\n",
1582 mfmsr(), mfspr(SPRN_SPRG0));
1583 printf("pvr = "REG" sprg1= "REG"\n",
1584 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
1585 printf("dec = "REG" sprg2= "REG"\n",
1586 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1587 printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1588 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
1589 #ifdef CONFIG_PPC_ISERIES
1590 if (firmware_has_feature(FW_FEATURE_ISERIES)) {
1591 struct paca_struct *ptrPaca;
1592 struct lppaca *ptrLpPaca;
1593 struct ItLpRegSave *ptrLpRegSave;
1595 /* Dump out relevant Paca data areas. */
1597 ptrPaca = get_paca();
1599 printf(" Local Processor Control Area (LpPaca): \n");
1600 ptrLpPaca = ptrPaca->lppaca_ptr;
1601 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1602 ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
1603 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1604 ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
1605 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
1607 printf(" Local Processor Register Save Area (LpRegSave): \n");
1608 ptrLpRegSave = ptrPaca->reg_save_ptr;
1609 printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n",
1610 ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
1611 printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n",
1612 ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
1613 printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n",
1614 ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
1624 val = read_spr(regno);
1626 write_spr(regno, val);
1629 printf("spr %lx = %lx\n", regno, read_spr(regno));
1636 * Stuff for reading and writing memory safely
1639 mread(unsigned long adrs, void *buf, int size)
1645 if (setjmp(bus_error_jmp) == 0) {
1646 catch_memory_errors = 1;
1652 *(u16 *)q = *(u16 *)p;
1655 *(u32 *)q = *(u32 *)p;
1658 *(u64 *)q = *(u64 *)p;
1661 for( ; n < size; ++n) {
1667 /* wait a little while to see if we get a machine check */
1671 catch_memory_errors = 0;
1676 mwrite(unsigned long adrs, void *buf, int size)
1682 if (setjmp(bus_error_jmp) == 0) {
1683 catch_memory_errors = 1;
1689 *(u16 *)p = *(u16 *)q;
1692 *(u32 *)p = *(u32 *)q;
1695 *(u64 *)p = *(u64 *)q;
1698 for ( ; n < size; ++n) {
1704 /* wait a little while to see if we get a machine check */
1708 printf("*** Error writing address %x\n", adrs + n);
1710 catch_memory_errors = 0;
1714 static int fault_type;
1715 static int fault_except;
1716 static char *fault_chars[] = { "--", "**", "##" };
1718 static int handle_fault(struct pt_regs *regs)
1720 fault_except = TRAP(regs);
1721 switch (TRAP(regs)) {
1733 longjmp(bus_error_jmp, 1);
1738 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1741 byterev(unsigned char *val, int size)
1747 SWAP(val[0], val[1], t);
1750 SWAP(val[0], val[3], t);
1751 SWAP(val[1], val[2], t);
1753 case 8: /* is there really any use for this? */
1754 SWAP(val[0], val[7], t);
1755 SWAP(val[1], val[6], t);
1756 SWAP(val[2], val[5], t);
1757 SWAP(val[3], val[4], t);
1765 static char *memex_help_string =
1766 "Memory examine command usage:\n"
1767 "m [addr] [flags] examine/change memory\n"
1768 " addr is optional. will start where left off.\n"
1769 " flags may include chars from this set:\n"
1770 " b modify by bytes (default)\n"
1771 " w modify by words (2 byte)\n"
1772 " l modify by longs (4 byte)\n"
1773 " d modify by doubleword (8 byte)\n"
1774 " r toggle reverse byte order mode\n"
1775 " n do not read memory (for i/o spaces)\n"
1776 " . ok to read (default)\n"
1777 "NOTE: flags are saved as defaults\n"
1780 static char *memex_subcmd_help_string =
1781 "Memory examine subcommands:\n"
1782 " hexval write this val to current location\n"
1783 " 'string' write chars from string to this location\n"
1784 " ' increment address\n"
1785 " ^ decrement address\n"
1786 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1787 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1788 " ` clear no-read flag\n"
1789 " ; stay at this addr\n"
1790 " v change to byte mode\n"
1791 " w change to word (2 byte) mode\n"
1792 " l change to long (4 byte) mode\n"
1793 " u change to doubleword (8 byte) mode\n"
1794 " m addr change current addr\n"
1795 " n toggle no-read flag\n"
1796 " r toggle byte reverse flag\n"
1797 " < count back up count bytes\n"
1798 " > count skip forward count bytes\n"
1799 " x exit this mode\n"
1805 int cmd, inc, i, nslash;
1807 unsigned char val[16];
1809 scanhex((void *)&adrs);
1812 printf(memex_help_string);
1818 while ((cmd = skipbl()) != '\n') {
1820 case 'b': size = 1; break;
1821 case 'w': size = 2; break;
1822 case 'l': size = 4; break;
1823 case 'd': size = 8; break;
1824 case 'r': brev = !brev; break;
1825 case 'n': mnoread = 1; break;
1826 case '.': mnoread = 0; break;
1835 n = mread(adrs, val, size);
1836 printf(REG"%c", adrs, brev? 'r': ' ');
1841 for (i = 0; i < n; ++i)
1842 printf("%.2x", val[i]);
1843 for (; i < size; ++i)
1844 printf("%s", fault_chars[fault_type]);
1851 for (i = 0; i < size; ++i)
1852 val[i] = n >> (i * 8);
1855 mwrite(adrs, val, size);
1868 else if( n == '\'' )
1870 for (i = 0; i < size; ++i)
1871 val[i] = n >> (i * 8);
1874 mwrite(adrs, val, size);
1911 adrs -= 1 << nslash;
1915 adrs += 1 << nslash;
1919 adrs += 1 << -nslash;
1923 adrs -= 1 << -nslash;
1926 scanhex((void *)&adrs);
1945 printf(memex_subcmd_help_string);
1960 case 'n': c = '\n'; break;
1961 case 'r': c = '\r'; break;
1962 case 'b': c = '\b'; break;
1963 case 't': c = '\t'; break;
1968 static void xmon_rawdump (unsigned long adrs, long ndump)
1971 unsigned char temp[16];
1973 for (n = ndump; n > 0;) {
1975 nr = mread(adrs, temp, r);
1977 for (m = 0; m < r; ++m) {
1979 printf("%.2x", temp[m]);
1981 printf("%s", fault_chars[fault_type]);
1990 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
1991 || ('a' <= (c) && (c) <= 'f') \
1992 || ('A' <= (c) && (c) <= 'F'))
1999 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
2001 scanhex((void *)&adrs);
2008 else if (nidump > MAX_DUMP)
2010 adrs += ppc_inst_dump(adrs, nidump, 1);
2012 } else if (c == 'r') {
2016 xmon_rawdump(adrs, ndump);
2023 else if (ndump > MAX_DUMP)
2025 prdump(adrs, ndump);
2032 prdump(unsigned long adrs, long ndump)
2034 long n, m, c, r, nr;
2035 unsigned char temp[16];
2037 for (n = ndump; n > 0;) {
2041 nr = mread(adrs, temp, r);
2043 for (m = 0; m < r; ++m) {
2044 if ((m & (sizeof(long) - 1)) == 0 && m > 0)
2047 printf("%.2x", temp[m]);
2049 printf("%s", fault_chars[fault_type]);
2051 for (; m < 16; ++m) {
2052 if ((m & (sizeof(long) - 1)) == 0)
2057 for (m = 0; m < r; ++m) {
2060 putchar(' ' <= c && c <= '~'? c: '.');
2073 typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr);
2076 generic_inst_dump(unsigned long adr, long count, int praddr,
2077 instruction_dump_func dump_func)
2080 unsigned long first_adr;
2081 unsigned long inst, last_inst = 0;
2082 unsigned char val[4];
2085 for (first_adr = adr; count > 0; --count, adr += 4) {
2086 nr = mread(adr, val, 4);
2089 const char *x = fault_chars[fault_type];
2090 printf(REG" %s%s%s%s\n", adr, x, x, x, x);
2094 inst = GETWORD(val);
2095 if (adr > first_adr && inst == last_inst) {
2105 printf(REG" %.8x", adr, inst);
2107 dump_func(inst, adr);
2110 return adr - first_adr;
2114 ppc_inst_dump(unsigned long adr, long count, int praddr)
2116 return generic_inst_dump(adr, count, praddr, print_insn_powerpc);
2120 print_address(unsigned long addr)
2122 xmon_print_symbol(addr, "\t# ", "");
2127 * Memory operations - move, set, print differences
2129 static unsigned long mdest; /* destination address */
2130 static unsigned long msrc; /* source address */
2131 static unsigned long mval; /* byte value to set memory to */
2132 static unsigned long mcount; /* # bytes to affect */
2133 static unsigned long mdiffs; /* max # differences to print */
2138 scanhex((void *)&mdest);
2139 if( termch != '\n' )
2141 scanhex((void *)(cmd == 's'? &mval: &msrc));
2142 if( termch != '\n' )
2144 scanhex((void *)&mcount);
2147 memmove((void *)mdest, (void *)msrc, mcount);
2150 memset((void *)mdest, mval, mcount);
2153 if( termch != '\n' )
2155 scanhex((void *)&mdiffs);
2156 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2162 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2167 for( n = nb; n > 0; --n )
2168 if( *p1++ != *p2++ )
2169 if( ++prt <= maxpr )
2170 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2171 p1[-1], p2 - 1, p2[-1]);
2173 printf("Total of %d differences\n", prt);
2176 static unsigned mend;
2177 static unsigned mask;
2183 unsigned char val[4];
2186 scanhex((void *)&mdest);
2187 if (termch != '\n') {
2189 scanhex((void *)&mend);
2190 if (termch != '\n') {
2192 scanhex((void *)&mval);
2194 if (termch != '\n') termch = 0;
2195 scanhex((void *)&mask);
2199 for (a = mdest; a < mend; a += 4) {
2200 if (mread(a, val, 4) == 4
2201 && ((GETWORD(val) ^ mval) & mask) == 0) {
2202 printf("%.16x: %.16x\n", a, GETWORD(val));
2209 static unsigned long mskip = 0x1000;
2210 static unsigned long mlim = 0xffffffff;
2220 if (termch != '\n') termch = 0;
2222 if (termch != '\n') termch = 0;
2225 for (a = mdest; a < mlim; a += mskip) {
2226 ok = mread(a, &v, 1);
2228 printf("%.8x .. ", a);
2229 } else if (!ok && ook)
2230 printf("%.8x\n", a - mskip);
2236 printf("%.8x\n", a - mskip);
2241 unsigned long args[8];
2244 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2245 unsigned long, unsigned long, unsigned long,
2246 unsigned long, unsigned long, unsigned long);
2249 if (!scanhex(&adrs))
2253 for (i = 0; i < 8; ++i)
2255 for (i = 0; i < 8; ++i) {
2256 if (!scanhex(&args[i]) || termch == '\n')
2260 func = (callfunc_t) adrs;
2262 if (setjmp(bus_error_jmp) == 0) {
2263 catch_memory_errors = 1;
2265 ret = func(args[0], args[1], args[2], args[3],
2266 args[4], args[5], args[6], args[7]);
2268 printf("return value is %x\n", ret);
2270 printf("*** %x exception occurred\n", fault_except);
2272 catch_memory_errors = 0;
2275 /* Input scanning routines */
2286 while( c == ' ' || c == '\t' )
2292 static char *regnames[N_PTREGS] = {
2293 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2294 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2295 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2296 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2297 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2303 "trap", "dar", "dsisr", "res"
2307 scanhex(unsigned long *vp)
2314 /* parse register name */
2318 for (i = 0; i < sizeof(regname) - 1; ++i) {
2327 for (i = 0; i < N_PTREGS; ++i) {
2328 if (strcmp(regnames[i], regname) == 0) {
2329 if (xmon_regs == NULL) {
2330 printf("regs not available\n");
2333 *vp = ((unsigned long *)xmon_regs)[i];
2337 printf("invalid register name '%%%s'\n", regname);
2341 /* skip leading "0x" if any */
2355 } else if (c == '$') {
2357 for (i=0; i<63; i++) {
2367 if (setjmp(bus_error_jmp) == 0) {
2368 catch_memory_errors = 1;
2370 *vp = kallsyms_lookup_name(tmpstr);
2373 catch_memory_errors = 0;
2375 printf("unknown symbol '%s'\n", tmpstr);
2410 if( '0' <= c && c <= '9' )
2412 if( 'A' <= c && c <= 'F' )
2413 return c - ('A' - 10);
2414 if( 'a' <= c && c <= 'f' )
2415 return c - ('a' - 10);
2420 getstring(char *s, int size)
2431 } while( c != ' ' && c != '\t' && c != '\n' );
2436 static char line[256];
2437 static char *lineptr;
2448 if (lineptr == NULL || *lineptr == 0) {
2449 if (xmon_gets(line, sizeof(line)) == NULL) {
2459 take_input(char *str)
2468 int type = inchar();
2470 static char tmp[64];
2475 xmon_print_symbol(addr, ": ", "\n");
2480 if (setjmp(bus_error_jmp) == 0) {
2481 catch_memory_errors = 1;
2483 addr = kallsyms_lookup_name(tmp);
2485 printf("%s: %lx\n", tmp, addr);
2487 printf("Symbol '%s' not found.\n", tmp);
2490 catch_memory_errors = 0;
2497 /* Print an address in numeric and symbolic form (if possible) */
2498 static void xmon_print_symbol(unsigned long address, const char *mid,
2502 const char *name = NULL;
2503 unsigned long offset, size;
2505 printf(REG, address);
2506 if (setjmp(bus_error_jmp) == 0) {
2507 catch_memory_errors = 1;
2509 name = kallsyms_lookup(address, &size, &offset, &modname,
2512 /* wait a little while to see if we get a machine check */
2516 catch_memory_errors = 0;
2519 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2521 printf(" [%s]", modname);
2523 printf("%s", after);
2527 static void dump_slb(void)
2532 printf("SLB contents of cpu %x\n", smp_processor_id());
2534 for (i = 0; i < SLB_NUM_ENTRIES; i++) {
2535 asm volatile("slbmfee %0,%1" : "=r" (tmp) : "r" (i));
2536 printf("%02d %016lx ", i, tmp);
2538 asm volatile("slbmfev %0,%1" : "=r" (tmp) : "r" (i));
2539 printf("%016lx\n", tmp);
2543 static void dump_stab(void)
2546 unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2548 printf("Segment table contents of cpu %x\n", smp_processor_id());
2550 for (i = 0; i < PAGE_SIZE/16; i++) {
2557 printf("%03d %016lx ", i, a);
2558 printf("%016lx\n", b);
2563 void dump_segments(void)
2565 if (cpu_has_feature(CPU_FTR_SLB))
2572 #ifdef CONFIG_PPC_STD_MMU_32
2573 void dump_segments(void)
2578 for (i = 0; i < 16; ++i)
2579 printf(" %x", mfsrin(i));
2584 void xmon_init(int enable)
2588 __debugger_ipi = xmon_ipi;
2589 __debugger_bpt = xmon_bpt;
2590 __debugger_sstep = xmon_sstep;
2591 __debugger_iabr_match = xmon_iabr_match;
2592 __debugger_dabr_match = xmon_dabr_match;
2593 __debugger_fault_handler = xmon_fault_handler;
2596 __debugger_ipi = NULL;
2597 __debugger_bpt = NULL;
2598 __debugger_sstep = NULL;
2599 __debugger_iabr_match = NULL;
2600 __debugger_dabr_match = NULL;
2601 __debugger_fault_handler = NULL;
2606 #ifdef CONFIG_MAGIC_SYSRQ
2607 static void sysrq_handle_xmon(int key, struct tty_struct *tty)
2609 /* ensure xmon is enabled */
2611 debugger(get_irq_regs());
2614 static struct sysrq_key_op sysrq_xmon_op =
2616 .handler = sysrq_handle_xmon,
2618 .action_msg = "Entering xmon",
2621 static int __init setup_xmon_sysrq(void)
2623 register_sysrq_key('x', &sysrq_xmon_op);
2626 __initcall(setup_xmon_sysrq);
2627 #endif /* CONFIG_MAGIC_SYSRQ */
2629 int __initdata xmon_early, xmon_off;
2631 static int __init early_parse_xmon(char *p)
2633 if (!p || strncmp(p, "early", 5) == 0) {
2634 /* just "xmon" is equivalent to "xmon=early" */
2637 } else if (strncmp(p, "on", 2) == 0)
2639 else if (strncmp(p, "off", 3) == 0)
2641 else if (strncmp(p, "nobt", 4) == 0)
2642 xmon_no_auto_backtrace = 1;
2648 early_param("xmon", early_parse_xmon);
2650 void __init xmon_setup(void)
2652 #ifdef CONFIG_XMON_DEFAULT
2660 #ifdef CONFIG_PPC_CELL
2664 u64 saved_mfc_sr1_RW;
2665 u32 saved_spu_runcntl_RW;
2666 unsigned long dump_addr;
2670 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
2672 static struct spu_info spu_info[XMON_NUM_SPUS];
2674 void xmon_register_spus(struct list_head *list)
2678 list_for_each_entry(spu, list, full_list) {
2679 if (spu->number >= XMON_NUM_SPUS) {
2684 spu_info[spu->number].spu = spu;
2685 spu_info[spu->number].stopped_ok = 0;
2686 spu_info[spu->number].dump_addr = (unsigned long)
2687 spu_info[spu->number].spu->local_store;
2691 static void stop_spus(void)
2697 for (i = 0; i < XMON_NUM_SPUS; i++) {
2698 if (!spu_info[i].spu)
2701 if (setjmp(bus_error_jmp) == 0) {
2702 catch_memory_errors = 1;
2705 spu = spu_info[i].spu;
2707 spu_info[i].saved_spu_runcntl_RW =
2708 in_be32(&spu->problem->spu_runcntl_RW);
2710 tmp = spu_mfc_sr1_get(spu);
2711 spu_info[i].saved_mfc_sr1_RW = tmp;
2713 tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
2714 spu_mfc_sr1_set(spu, tmp);
2719 spu_info[i].stopped_ok = 1;
2721 printf("Stopped spu %.2d (was %s)\n", i,
2722 spu_info[i].saved_spu_runcntl_RW ?
2723 "running" : "stopped");
2725 catch_memory_errors = 0;
2726 printf("*** Error stopping spu %.2d\n", i);
2728 catch_memory_errors = 0;
2732 static void restart_spus(void)
2737 for (i = 0; i < XMON_NUM_SPUS; i++) {
2738 if (!spu_info[i].spu)
2741 if (!spu_info[i].stopped_ok) {
2742 printf("*** Error, spu %d was not successfully stopped"
2743 ", not restarting\n", i);
2747 if (setjmp(bus_error_jmp) == 0) {
2748 catch_memory_errors = 1;
2751 spu = spu_info[i].spu;
2752 spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
2753 out_be32(&spu->problem->spu_runcntl_RW,
2754 spu_info[i].saved_spu_runcntl_RW);
2759 printf("Restarted spu %.2d\n", i);
2761 catch_memory_errors = 0;
2762 printf("*** Error restarting spu %.2d\n", i);
2764 catch_memory_errors = 0;
2768 #define DUMP_WIDTH 23
2769 #define DUMP_VALUE(format, field, value) \
2771 if (setjmp(bus_error_jmp) == 0) { \
2772 catch_memory_errors = 1; \
2774 printf(" %-*s = "format"\n", DUMP_WIDTH, \
2779 catch_memory_errors = 0; \
2780 printf(" %-*s = *** Error reading field.\n", \
2781 DUMP_WIDTH, #field); \
2783 catch_memory_errors = 0; \
2786 #define DUMP_FIELD(obj, format, field) \
2787 DUMP_VALUE(format, field, obj->field)
2789 static void dump_spu_fields(struct spu *spu)
2791 printf("Dumping spu fields at address %p:\n", spu);
2793 DUMP_FIELD(spu, "0x%x", number);
2794 DUMP_FIELD(spu, "%s", name);
2795 DUMP_FIELD(spu, "%s", devnode->full_name);
2796 DUMP_FIELD(spu, "0x%x", nid);
2797 DUMP_FIELD(spu, "0x%lx", local_store_phys);
2798 DUMP_FIELD(spu, "0x%p", local_store);
2799 DUMP_FIELD(spu, "0x%lx", ls_size);
2800 DUMP_FIELD(spu, "0x%x", node);
2801 DUMP_FIELD(spu, "0x%lx", flags);
2802 DUMP_FIELD(spu, "0x%lx", dar);
2803 DUMP_FIELD(spu, "0x%lx", dsisr);
2804 DUMP_FIELD(spu, "%d", class_0_pending);
2805 DUMP_FIELD(spu, "0x%lx", irqs[0]);
2806 DUMP_FIELD(spu, "0x%lx", irqs[1]);
2807 DUMP_FIELD(spu, "0x%lx", irqs[2]);
2808 DUMP_FIELD(spu, "0x%x", slb_replace);
2809 DUMP_FIELD(spu, "%d", pid);
2810 DUMP_FIELD(spu, "%d", prio);
2811 DUMP_FIELD(spu, "0x%p", mm);
2812 DUMP_FIELD(spu, "0x%p", ctx);
2813 DUMP_FIELD(spu, "0x%p", rq);
2814 DUMP_FIELD(spu, "0x%p", timestamp);
2815 DUMP_FIELD(spu, "0x%lx", problem_phys);
2816 DUMP_FIELD(spu, "0x%p", problem);
2817 DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
2818 in_be32(&spu->problem->spu_runcntl_RW));
2819 DUMP_VALUE("0x%x", problem->spu_status_R,
2820 in_be32(&spu->problem->spu_status_R));
2821 DUMP_VALUE("0x%x", problem->spu_npc_RW,
2822 in_be32(&spu->problem->spu_npc_RW));
2823 DUMP_FIELD(spu, "0x%p", priv1);
2826 DUMP_VALUE("0x%lx", priv1->mfc_sr1_RW,
2827 in_be64(&spu->priv1->mfc_sr1_RW));
2830 DUMP_FIELD(spu, "0x%p", priv2);
2834 spu_inst_dump(unsigned long adr, long count, int praddr)
2836 return generic_inst_dump(adr, count, praddr, print_insn_spu);
2839 static void dump_spu_ls(unsigned long num, int subcmd)
2841 unsigned long offset, addr, ls_addr;
2843 if (setjmp(bus_error_jmp) == 0) {
2844 catch_memory_errors = 1;
2846 ls_addr = (unsigned long)spu_info[num].spu->local_store;
2850 catch_memory_errors = 0;
2851 printf("*** Error: accessing spu info for spu %d\n", num);
2854 catch_memory_errors = 0;
2856 if (scanhex(&offset))
2857 addr = ls_addr + offset;
2859 addr = spu_info[num].dump_addr;
2861 if (addr >= ls_addr + LS_SIZE) {
2862 printf("*** Error: address outside of local store\n");
2868 addr += spu_inst_dump(addr, 16, 1);
2878 spu_info[num].dump_addr = addr;
2881 static int do_spu_cmd(void)
2883 static unsigned long num = 0;
2884 int cmd, subcmd = 0;
2896 if (isxdigit(subcmd) || subcmd == '\n')
2900 if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
2901 printf("*** Error: invalid spu number\n");
2907 dump_spu_fields(spu_info[num].spu);
2910 dump_spu_ls(num, subcmd);
2921 #else /* ! CONFIG_PPC_CELL */
2922 static int do_spu_cmd(void)