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>
52 #define scanhex xmon_scanhex
53 #define skipbl xmon_skipbl
56 cpumask_t cpus_in_xmon = CPU_MASK_NONE;
57 static unsigned long xmon_taken = 1;
58 static int xmon_owner;
60 #endif /* CONFIG_SMP */
62 static unsigned long in_xmon = 0;
64 static unsigned long adrs;
66 #define MAX_DUMP (128 * 1024)
67 static unsigned long ndump = 64;
68 static unsigned long nidump = 16;
69 static unsigned long ncsum = 4096;
71 static char tmpstr[128];
73 #define JMP_BUF_LEN 23
74 static long bus_error_jmp[JMP_BUF_LEN];
75 static int catch_memory_errors;
76 static long *xmon_fault_jmp[NR_CPUS];
77 #define setjmp xmon_setjmp
78 #define longjmp xmon_longjmp
80 /* Breakpoint stuff */
82 unsigned long address;
83 unsigned int instr[2];
89 /* Bits in bpt.enabled */
90 #define BP_IABR_TE 1 /* IABR translation enabled */
96 static struct bpt bpts[NBPTS];
97 static struct bpt dabr;
98 static struct bpt *iabr;
99 static unsigned bpinstr = 0x7fe00008; /* trap */
101 #define BP_NUM(bp) ((bp) - bpts + 1)
104 static int cmds(struct pt_regs *);
105 static int mread(unsigned long, void *, int);
106 static int mwrite(unsigned long, void *, int);
107 static int handle_fault(struct pt_regs *);
108 static void byterev(unsigned char *, int);
109 static void memex(void);
110 static int bsesc(void);
111 static void dump(void);
112 static void prdump(unsigned long, long);
113 static int ppc_inst_dump(unsigned long, long, int);
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 void xmon_enter(void);
158 extern void xmon_leave(void);
160 extern long setjmp(long *);
161 extern void longjmp(long *, long);
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_PPC_CELL
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)\
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"
238 static struct pt_regs *xmon_regs;
240 static inline void sync(void)
242 asm volatile("sync; isync");
245 static inline void store_inst(void *p)
247 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
250 static inline void cflush(void *p)
252 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
255 static inline void cinval(void *p)
257 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
261 * Disable surveillance (the service processor watchdog function)
262 * while we are in xmon.
263 * XXX we should re-enable it when we leave. :)
265 #define SURVEILLANCE_TOKEN 9000
267 static inline void disable_surveillance(void)
269 #ifdef CONFIG_PPC_PSERIES
270 /* Since this can't be a module, args should end up below 4GB. */
271 static struct rtas_args args;
274 * At this point we have got all the cpus we can into
275 * xmon, so there is hopefully no other cpu calling RTAS
276 * at the moment, even though we don't take rtas.lock.
277 * If we did try to take rtas.lock there would be a
278 * real possibility of deadlock.
280 args.token = rtas_token("set-indicator");
281 if (args.token == RTAS_UNKNOWN_SERVICE)
285 args.rets = &args.args[3];
286 args.args[0] = SURVEILLANCE_TOKEN;
289 enter_rtas(__pa(&args));
290 #endif /* CONFIG_PPC_PSERIES */
294 static int xmon_speaker;
296 static void get_output_lock(void)
298 int me = smp_processor_id() + 0x100;
299 int last_speaker = 0, prev;
302 if (xmon_speaker == me)
305 if (xmon_speaker == 0) {
306 last_speaker = cmpxchg(&xmon_speaker, 0, me);
307 if (last_speaker == 0)
311 while (xmon_speaker == last_speaker) {
314 /* hostile takeover */
315 prev = cmpxchg(&xmon_speaker, last_speaker, me);
316 if (prev == last_speaker)
323 static void release_output_lock(void)
329 static int xmon_core(struct pt_regs *regs, int fromipi)
334 long recurse_jmp[JMP_BUF_LEN];
335 unsigned long offset;
339 unsigned long timeout;
343 mtmsr(msr & ~MSR_EE); /* disable interrupts */
345 bp = in_breakpoint_table(regs->nip, &offset);
347 regs->nip = bp->address + offset;
348 atomic_dec(&bp->ref_count);
354 cpu = smp_processor_id();
355 if (cpu_isset(cpu, cpus_in_xmon)) {
358 printf("cpu 0x%x: Exception %lx %s in xmon, "
359 "returning to main loop\n",
360 cpu, regs->trap, getvecname(TRAP(regs)));
361 release_output_lock();
362 longjmp(xmon_fault_jmp[cpu], 1);
365 if (setjmp(recurse_jmp) != 0) {
366 if (!in_xmon || !xmon_gate) {
368 printf("xmon: WARNING: bad recursive fault "
369 "on cpu 0x%x\n", cpu);
370 release_output_lock();
373 secondary = !(xmon_taken && cpu == xmon_owner);
377 xmon_fault_jmp[cpu] = recurse_jmp;
378 cpu_set(cpu, cpus_in_xmon);
381 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
382 bp = at_breakpoint(regs->nip);
383 if (bp || (regs->msr & MSR_RI) == 0)
390 printf("cpu 0x%x stopped at breakpoint 0x%x (",
392 xmon_print_symbol(regs->nip, " ", ")\n");
394 if ((regs->msr & MSR_RI) == 0)
395 printf("WARNING: exception is not recoverable, "
397 release_output_lock();
402 while (secondary && !xmon_gate) {
406 secondary = test_and_set_bit(0, &in_xmon);
411 if (!secondary && !xmon_gate) {
412 /* we are the first cpu to come in */
413 /* interrupt other cpu(s) */
414 int ncpus = num_online_cpus();
419 smp_send_debugger_break(MSG_ALL_BUT_SELF);
420 /* wait for other cpus to come in */
421 for (timeout = 100000000; timeout != 0; --timeout) {
422 if (cpus_weight(cpus_in_xmon) >= ncpus)
428 disable_surveillance();
429 /* for breakpoint or single step, print the current instr. */
430 if (bp || TRAP(regs) == 0xd00)
431 ppc_inst_dump(regs->nip, 1, 0);
432 printf("enter ? for help\n");
441 if (cpu == xmon_owner) {
442 if (!test_and_set_bit(0, &xmon_taken)) {
447 while (cpu == xmon_owner)
461 /* have switched to some other cpu */
466 cpu_clear(cpu, cpus_in_xmon);
467 xmon_fault_jmp[cpu] = NULL;
469 /* UP is simple... */
471 printf("Exception %lx %s in xmon, returning to main loop\n",
472 regs->trap, getvecname(TRAP(regs)));
473 longjmp(xmon_fault_jmp[0], 1);
475 if (setjmp(recurse_jmp) == 0) {
476 xmon_fault_jmp[0] = recurse_jmp;
480 bp = at_breakpoint(regs->nip);
482 printf("Stopped at breakpoint %x (", BP_NUM(bp));
483 xmon_print_symbol(regs->nip, " ", ")\n");
485 if ((regs->msr & MSR_RI) == 0)
486 printf("WARNING: exception is not recoverable, "
489 disable_surveillance();
490 /* for breakpoint or single step, print the current instr. */
491 if (bp || TRAP(regs) == 0xd00)
492 ppc_inst_dump(regs->nip, 1, 0);
493 printf("enter ? for help\n");
502 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
503 bp = at_breakpoint(regs->nip);
505 int stepped = emulate_step(regs, bp->instr[0]);
507 regs->nip = (unsigned long) &bp->instr[0];
508 atomic_inc(&bp->ref_count);
509 } else if (stepped < 0) {
510 printf("Couldn't single-step %s instruction\n",
511 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
518 mtmsr(msr); /* restore interrupt enable */
520 return cmd != 'X' && cmd != EOF;
523 int xmon(struct pt_regs *excp)
528 xmon_save_regs(®s);
532 return xmon_core(excp, 0);
536 irqreturn_t xmon_irq(int irq, void *d)
539 local_irq_save(flags);
540 printf("Keyboard interrupt\n");
541 xmon(get_irq_regs());
542 local_irq_restore(flags);
546 static int xmon_bpt(struct pt_regs *regs)
549 unsigned long offset;
551 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
554 /* Are we at the trap at bp->instr[1] for some bp? */
555 bp = in_breakpoint_table(regs->nip, &offset);
556 if (bp != NULL && offset == 4) {
557 regs->nip = bp->address + 4;
558 atomic_dec(&bp->ref_count);
562 /* Are we at a breakpoint? */
563 bp = at_breakpoint(regs->nip);
572 static int xmon_sstep(struct pt_regs *regs)
580 static int xmon_dabr_match(struct pt_regs *regs)
582 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
584 if (dabr.enabled == 0)
590 static int xmon_iabr_match(struct pt_regs *regs)
592 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
600 static int xmon_ipi(struct pt_regs *regs)
603 if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
609 static int xmon_fault_handler(struct pt_regs *regs)
612 unsigned long offset;
614 if (in_xmon && catch_memory_errors)
615 handle_fault(regs); /* doesn't return */
617 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
618 bp = in_breakpoint_table(regs->nip, &offset);
620 regs->nip = bp->address + offset;
621 atomic_dec(&bp->ref_count);
628 static struct bpt *at_breakpoint(unsigned long pc)
634 for (i = 0; i < NBPTS; ++i, ++bp)
635 if (bp->enabled && pc == bp->address)
640 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
644 off = nip - (unsigned long) bpts;
645 if (off >= sizeof(bpts))
647 off %= sizeof(struct bpt);
648 if (off != offsetof(struct bpt, instr[0])
649 && off != offsetof(struct bpt, instr[1]))
651 *offp = off - offsetof(struct bpt, instr[0]);
652 return (struct bpt *) (nip - off);
655 static struct bpt *new_breakpoint(unsigned long a)
660 bp = at_breakpoint(a);
664 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
665 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
667 bp->instr[1] = bpinstr;
668 store_inst(&bp->instr[1]);
673 printf("Sorry, no free breakpoints. Please clear one first.\n");
677 static void insert_bpts(void)
683 for (i = 0; i < NBPTS; ++i, ++bp) {
684 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
686 if (mread(bp->address, &bp->instr[0], 4) != 4) {
687 printf("Couldn't read instruction at %lx, "
688 "disabling breakpoint there\n", bp->address);
692 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
693 printf("Breakpoint at %lx is on an mtmsrd or rfid "
694 "instruction, disabling it\n", bp->address);
698 store_inst(&bp->instr[0]);
699 if (bp->enabled & BP_IABR)
701 if (mwrite(bp->address, &bpinstr, 4) != 4) {
702 printf("Couldn't write instruction at %lx, "
703 "disabling breakpoint there\n", bp->address);
704 bp->enabled &= ~BP_TRAP;
707 store_inst((void *)bp->address);
711 static void insert_cpu_bpts(void)
714 set_dabr(dabr.address | (dabr.enabled & 7));
715 if (iabr && cpu_has_feature(CPU_FTR_IABR))
716 mtspr(SPRN_IABR, iabr->address
717 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
720 static void remove_bpts(void)
727 for (i = 0; i < NBPTS; ++i, ++bp) {
728 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
730 if (mread(bp->address, &instr, 4) == 4
732 && mwrite(bp->address, &bp->instr, 4) != 4)
733 printf("Couldn't remove breakpoint at %lx\n",
736 store_inst((void *)bp->address);
740 static void remove_cpu_bpts(void)
743 if (cpu_has_feature(CPU_FTR_IABR))
747 /* Command interpreting routine */
748 static char *last_cmd;
751 cmds(struct pt_regs *excp)
758 if (!xmon_no_auto_backtrace) {
759 xmon_no_auto_backtrace = 1;
760 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
765 printf("%x:", smp_processor_id());
766 #endif /* CONFIG_SMP */
772 if (last_cmd == NULL)
774 take_input(last_cmd);
808 prregs(excp); /* print regs */
823 if (do_spu_cmd() == 0)
832 printf(" <no input ...>\n");
854 #ifdef CONFIG_PPC_STD_MMU
860 printf("Unrecognized command: ");
862 if (' ' < cmd && cmd <= '~')
865 printf("\\x%x", cmd);
867 } while (cmd != '\n');
868 printf(" (type ? for help)\n");
875 * Step a single instruction.
876 * Some instructions we emulate, others we execute with MSR_SE set.
878 static int do_step(struct pt_regs *regs)
883 /* check we are in 64-bit kernel mode, translation enabled */
884 if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
885 if (mread(regs->nip, &instr, 4) == 4) {
886 stepped = emulate_step(regs, instr);
888 printf("Couldn't single-step %s instruction\n",
889 (IS_RFID(instr)? "rfid": "mtmsrd"));
893 regs->trap = 0xd00 | (regs->trap & 1);
894 printf("stepped to ");
895 xmon_print_symbol(regs->nip, " ", "\n");
896 ppc_inst_dump(regs->nip, 1, 0);
905 static void bootcmds(void)
911 ppc_md.restart(NULL);
918 static int cpu_cmd(void)
925 if (!scanhex(&cpu)) {
926 /* print cpus waiting or in xmon */
927 printf("cpus stopped:");
929 for (cpu = 0; cpu < NR_CPUS; ++cpu) {
930 if (cpu_isset(cpu, cpus_in_xmon)) {
936 printf("-%x", cpu - 1);
941 printf("-%x", NR_CPUS - 1);
945 /* try to switch to cpu specified */
946 if (!cpu_isset(cpu, cpus_in_xmon)) {
947 printf("cpu 0x%x isn't in xmon\n", cpu);
954 while (!xmon_taken) {
955 if (--timeout == 0) {
956 if (test_and_set_bit(0, &xmon_taken))
958 /* take control back */
960 xmon_owner = smp_processor_id();
961 printf("cpu %u didn't take control\n", cpu);
969 #endif /* CONFIG_SMP */
972 static unsigned short fcstab[256] = {
973 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
974 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
975 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
976 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
977 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
978 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
979 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
980 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
981 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
982 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
983 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
984 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
985 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
986 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
987 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
988 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
989 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
990 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
991 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
992 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
993 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
994 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
995 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
996 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
997 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
998 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
999 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1000 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1001 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1002 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1003 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1004 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1007 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1016 if (!scanhex(&adrs))
1018 if (!scanhex(&ncsum))
1021 for (i = 0; i < ncsum; ++i) {
1022 if (mread(adrs+i, &v, 1) == 0) {
1023 printf("csum stopped at %x\n", adrs+i);
1028 printf("%x\n", fcs);
1032 * Check if this is a suitable place to put a breakpoint.
1034 static long check_bp_loc(unsigned long addr)
1039 if (!is_kernel_addr(addr)) {
1040 printf("Breakpoints may only be placed at kernel addresses\n");
1043 if (!mread(addr, &instr, sizeof(instr))) {
1044 printf("Can't read instruction at address %lx\n", addr);
1047 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1048 printf("Breakpoints may not be placed on mtmsrd or rfid "
1055 static char *breakpoint_help_string =
1056 "Breakpoint command usage:\n"
1057 "b show breakpoints\n"
1058 "b <addr> [cnt] set breakpoint at given instr addr\n"
1059 "bc clear all breakpoints\n"
1060 "bc <n/addr> clear breakpoint number n or at addr\n"
1061 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1062 "bd <addr> [cnt] set hardware data breakpoint\n"
1072 const char badaddr[] = "Only kernel addresses are permitted "
1073 "for breakpoints\n";
1078 case 'd': /* bd - hardware data breakpoint */
1083 else if (cmd == 'w')
1089 if (scanhex(&dabr.address)) {
1090 if (!is_kernel_addr(dabr.address)) {
1095 dabr.enabled = mode | BP_DABR;
1099 case 'i': /* bi - hardware instr breakpoint */
1100 if (!cpu_has_feature(CPU_FTR_IABR)) {
1101 printf("Hardware instruction breakpoint "
1102 "not supported on this cpu\n");
1106 iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1111 if (!check_bp_loc(a))
1113 bp = new_breakpoint(a);
1115 bp->enabled |= BP_IABR | BP_IABR_TE;
1123 /* clear all breakpoints */
1124 for (i = 0; i < NBPTS; ++i)
1125 bpts[i].enabled = 0;
1128 printf("All breakpoints cleared\n");
1132 if (a <= NBPTS && a >= 1) {
1133 /* assume a breakpoint number */
1134 bp = &bpts[a-1]; /* bp nums are 1 based */
1136 /* assume a breakpoint address */
1137 bp = at_breakpoint(a);
1139 printf("No breakpoint at %x\n", a);
1144 printf("Cleared breakpoint %x (", BP_NUM(bp));
1145 xmon_print_symbol(bp->address, " ", ")\n");
1153 printf(breakpoint_help_string);
1158 /* print all breakpoints */
1159 printf(" type address\n");
1161 printf(" data "REG" [", dabr.address);
1162 if (dabr.enabled & 1)
1164 if (dabr.enabled & 2)
1168 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1171 printf("%2x %s ", BP_NUM(bp),
1172 (bp->enabled & BP_IABR)? "inst": "trap");
1173 xmon_print_symbol(bp->address, " ", "\n");
1178 if (!check_bp_loc(a))
1180 bp = new_breakpoint(a);
1182 bp->enabled |= BP_TRAP;
1187 /* Very cheap human name for vector lookup. */
1189 const char *getvecname(unsigned long vec)
1194 case 0x100: ret = "(System Reset)"; break;
1195 case 0x200: ret = "(Machine Check)"; break;
1196 case 0x300: ret = "(Data Access)"; break;
1197 case 0x380: ret = "(Data SLB Access)"; break;
1198 case 0x400: ret = "(Instruction Access)"; break;
1199 case 0x480: ret = "(Instruction SLB Access)"; break;
1200 case 0x500: ret = "(Hardware Interrupt)"; break;
1201 case 0x600: ret = "(Alignment)"; break;
1202 case 0x700: ret = "(Program Check)"; break;
1203 case 0x800: ret = "(FPU Unavailable)"; break;
1204 case 0x900: ret = "(Decrementer)"; break;
1205 case 0xc00: ret = "(System Call)"; break;
1206 case 0xd00: ret = "(Single Step)"; break;
1207 case 0xf00: ret = "(Performance Monitor)"; break;
1208 case 0xf20: ret = "(Altivec Unavailable)"; break;
1209 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1215 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1216 unsigned long *endp)
1218 unsigned long size, offset;
1222 *startp = *endp = 0;
1225 if (setjmp(bus_error_jmp) == 0) {
1226 catch_memory_errors = 1;
1228 name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr);
1230 *startp = pc - offset;
1231 *endp = pc - offset + size;
1235 catch_memory_errors = 0;
1238 static int xmon_depth_to_print = 64;
1241 #define LRSAVE_OFFSET 0x10
1242 #define REG_FRAME_MARKER 0x7265677368657265ul /* "regshere" */
1243 #define MARKER_OFFSET 0x60
1244 #define REGS_OFFSET 0x70
1246 #define LRSAVE_OFFSET 4
1247 #define REG_FRAME_MARKER 0x72656773
1248 #define MARKER_OFFSET 8
1249 #define REGS_OFFSET 16
1252 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1256 unsigned long newsp;
1257 unsigned long marker;
1259 struct pt_regs regs;
1262 if (sp < PAGE_OFFSET) {
1264 printf("SP (%lx) is in userspace\n", sp);
1268 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1269 || !mread(sp, &newsp, sizeof(unsigned long))) {
1270 printf("Couldn't read stack frame at %lx\n", sp);
1275 * For the first stack frame, try to work out if
1276 * LR and/or the saved LR value in the bottommost
1277 * stack frame are valid.
1279 if ((pc | lr) != 0) {
1280 unsigned long fnstart, fnend;
1281 unsigned long nextip;
1284 get_function_bounds(pc, &fnstart, &fnend);
1287 mread(newsp + LRSAVE_OFFSET, &nextip,
1288 sizeof(unsigned long));
1290 if (lr < PAGE_OFFSET
1291 || (fnstart <= lr && lr < fnend))
1293 } else if (lr == nextip) {
1295 } else if (lr >= PAGE_OFFSET
1296 && !(fnstart <= lr && lr < fnend)) {
1297 printf("[link register ] ");
1298 xmon_print_symbol(lr, " ", "\n");
1301 printf("["REG"] ", sp);
1302 xmon_print_symbol(ip, " ", " (unreliable)\n");
1307 printf("["REG"] ", sp);
1308 xmon_print_symbol(ip, " ", "\n");
1311 /* Look for "regshere" marker to see if this is
1312 an exception frame. */
1313 if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1314 && marker == REG_FRAME_MARKER) {
1315 if (mread(sp + REGS_OFFSET, ®s, sizeof(regs))
1317 printf("Couldn't read registers at %lx\n",
1321 printf("--- Exception: %lx %s at ", regs.trap,
1322 getvecname(TRAP(®s)));
1325 xmon_print_symbol(pc, " ", "\n");
1332 } while (count++ < xmon_depth_to_print);
1335 static void backtrace(struct pt_regs *excp)
1340 xmon_show_stack(sp, 0, 0);
1342 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1346 static void print_bug_trap(struct pt_regs *regs)
1348 struct bug_entry *bug;
1351 if (regs->msr & MSR_PR)
1352 return; /* not in kernel */
1353 addr = regs->nip; /* address of trap instruction */
1354 if (addr < PAGE_OFFSET)
1356 bug = find_bug(regs->nip);
1359 if (bug->line & BUG_WARNING_TRAP)
1362 printf("kernel BUG in %s at %s:%d!\n",
1363 bug->function, bug->file, (unsigned int)bug->line);
1366 void excprint(struct pt_regs *fp)
1371 printf("cpu 0x%x: ", smp_processor_id());
1372 #endif /* CONFIG_SMP */
1375 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1377 xmon_print_symbol(fp->nip, ": ", "\n");
1379 printf(" lr: ", fp->link);
1380 xmon_print_symbol(fp->link, ": ", "\n");
1382 printf(" sp: %lx\n", fp->gpr[1]);
1383 printf(" msr: %lx\n", fp->msr);
1385 if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1386 printf(" dar: %lx\n", fp->dar);
1388 printf(" dsisr: %lx\n", fp->dsisr);
1391 printf(" current = 0x%lx\n", current);
1393 printf(" paca = 0x%lx\n", get_paca());
1396 printf(" pid = %ld, comm = %s\n",
1397 current->pid, current->comm);
1404 void prregs(struct pt_regs *fp)
1408 struct pt_regs regs;
1410 if (scanhex(&base)) {
1411 if (setjmp(bus_error_jmp) == 0) {
1412 catch_memory_errors = 1;
1414 regs = *(struct pt_regs *)base;
1418 catch_memory_errors = 0;
1419 printf("*** Error reading registers from "REG"\n",
1423 catch_memory_errors = 0;
1428 if (FULL_REGS(fp)) {
1429 for (n = 0; n < 16; ++n)
1430 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1431 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1433 for (n = 0; n < 7; ++n)
1434 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1435 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1438 for (n = 0; n < 32; ++n) {
1439 printf("R%.2d = %.8x%s", n, fp->gpr[n],
1440 (n & 3) == 3? "\n": " ");
1441 if (n == 12 && !FULL_REGS(fp)) {
1448 xmon_print_symbol(fp->nip, " ", "\n");
1450 xmon_print_symbol(fp->link, " ", "\n");
1451 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
1452 printf("ctr = "REG" xer = "REG" trap = %4lx\n",
1453 fp->ctr, fp->xer, fp->trap);
1455 if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1456 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1459 void cacheflush(void)
1462 unsigned long nflush;
1467 scanhex((void *)&adrs);
1472 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1473 if (setjmp(bus_error_jmp) == 0) {
1474 catch_memory_errors = 1;
1478 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1479 cflush((void *) adrs);
1481 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1482 cinval((void *) adrs);
1485 /* wait a little while to see if we get a machine check */
1488 catch_memory_errors = 0;
1494 unsigned int instrs[2];
1495 unsigned long (*code)(void);
1496 unsigned long ret = -1UL;
1498 unsigned long opd[3];
1500 opd[0] = (unsigned long)instrs;
1503 code = (unsigned long (*)(void)) opd;
1505 code = (unsigned long (*)(void)) instrs;
1508 /* mfspr r3,n; blr */
1509 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1510 instrs[1] = 0x4e800020;
1512 store_inst(instrs+1);
1514 if (setjmp(bus_error_jmp) == 0) {
1515 catch_memory_errors = 1;
1521 /* wait a little while to see if we get a machine check */
1530 write_spr(int n, unsigned long val)
1532 unsigned int instrs[2];
1533 unsigned long (*code)(unsigned long);
1535 unsigned long opd[3];
1537 opd[0] = (unsigned long)instrs;
1540 code = (unsigned long (*)(unsigned long)) opd;
1542 code = (unsigned long (*)(unsigned long)) instrs;
1545 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1546 instrs[1] = 0x4e800020;
1548 store_inst(instrs+1);
1550 if (setjmp(bus_error_jmp) == 0) {
1551 catch_memory_errors = 1;
1557 /* wait a little while to see if we get a machine check */
1563 static unsigned long regno;
1564 extern char exc_prolog;
1565 extern char dec_exc;
1567 void super_regs(void)
1574 unsigned long sp, toc;
1575 asm("mr %0,1" : "=r" (sp) :);
1576 asm("mr %0,2" : "=r" (toc) :);
1578 printf("msr = "REG" sprg0= "REG"\n",
1579 mfmsr(), mfspr(SPRN_SPRG0));
1580 printf("pvr = "REG" sprg1= "REG"\n",
1581 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
1582 printf("dec = "REG" sprg2= "REG"\n",
1583 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1584 printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1585 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
1586 #ifdef CONFIG_PPC_ISERIES
1587 if (firmware_has_feature(FW_FEATURE_ISERIES)) {
1588 struct paca_struct *ptrPaca;
1589 struct lppaca *ptrLpPaca;
1590 struct ItLpRegSave *ptrLpRegSave;
1592 /* Dump out relevant Paca data areas. */
1594 ptrPaca = get_paca();
1596 printf(" Local Processor Control Area (LpPaca): \n");
1597 ptrLpPaca = ptrPaca->lppaca_ptr;
1598 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1599 ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
1600 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1601 ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
1602 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
1604 printf(" Local Processor Register Save Area (LpRegSave): \n");
1605 ptrLpRegSave = ptrPaca->reg_save_ptr;
1606 printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n",
1607 ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
1608 printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n",
1609 ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
1610 printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n",
1611 ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
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)
2529 printf("SLB contents of cpu %x\n", smp_processor_id());
2531 for (i = 0; i < SLB_NUM_ENTRIES; i++) {
2532 asm volatile("slbmfee %0,%1" : "=r" (tmp) : "r" (i));
2533 printf("%02d %016lx ", i, tmp);
2535 asm volatile("slbmfev %0,%1" : "=r" (tmp) : "r" (i));
2536 printf("%016lx\n", tmp);
2540 static void dump_stab(void)
2543 unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2545 printf("Segment table contents of cpu %x\n", smp_processor_id());
2547 for (i = 0; i < PAGE_SIZE/16; i++) {
2554 printf("%03d %016lx ", i, a);
2555 printf("%016lx\n", b);
2560 void dump_segments(void)
2562 if (cpu_has_feature(CPU_FTR_SLB))
2569 #ifdef CONFIG_PPC_STD_MMU_32
2570 void dump_segments(void)
2575 for (i = 0; i < 16; ++i)
2576 printf(" %x", mfsrin(i));
2581 void xmon_init(int enable)
2585 __debugger_ipi = xmon_ipi;
2586 __debugger_bpt = xmon_bpt;
2587 __debugger_sstep = xmon_sstep;
2588 __debugger_iabr_match = xmon_iabr_match;
2589 __debugger_dabr_match = xmon_dabr_match;
2590 __debugger_fault_handler = xmon_fault_handler;
2593 __debugger_ipi = NULL;
2594 __debugger_bpt = NULL;
2595 __debugger_sstep = NULL;
2596 __debugger_iabr_match = NULL;
2597 __debugger_dabr_match = NULL;
2598 __debugger_fault_handler = NULL;
2603 #ifdef CONFIG_MAGIC_SYSRQ
2604 static void sysrq_handle_xmon(int key, struct tty_struct *tty)
2606 /* ensure xmon is enabled */
2608 debugger(get_irq_regs());
2611 static struct sysrq_key_op sysrq_xmon_op =
2613 .handler = sysrq_handle_xmon,
2615 .action_msg = "Entering xmon",
2618 static int __init setup_xmon_sysrq(void)
2620 register_sysrq_key('x', &sysrq_xmon_op);
2623 __initcall(setup_xmon_sysrq);
2624 #endif /* CONFIG_MAGIC_SYSRQ */
2626 int __initdata xmon_early, xmon_off;
2628 static int __init early_parse_xmon(char *p)
2630 if (!p || strncmp(p, "early", 5) == 0) {
2631 /* just "xmon" is equivalent to "xmon=early" */
2634 } else if (strncmp(p, "on", 2) == 0)
2636 else if (strncmp(p, "off", 3) == 0)
2638 else if (strncmp(p, "nobt", 4) == 0)
2639 xmon_no_auto_backtrace = 1;
2645 early_param("xmon", early_parse_xmon);
2647 void __init xmon_setup(void)
2649 #ifdef CONFIG_XMON_DEFAULT
2657 #ifdef CONFIG_PPC_CELL
2661 u64 saved_mfc_sr1_RW;
2662 u32 saved_spu_runcntl_RW;
2663 unsigned long dump_addr;
2667 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
2669 static struct spu_info spu_info[XMON_NUM_SPUS];
2671 void xmon_register_spus(struct list_head *list)
2675 list_for_each_entry(spu, list, full_list) {
2676 if (spu->number >= XMON_NUM_SPUS) {
2681 spu_info[spu->number].spu = spu;
2682 spu_info[spu->number].stopped_ok = 0;
2683 spu_info[spu->number].dump_addr = (unsigned long)
2684 spu_info[spu->number].spu->local_store;
2688 static void stop_spus(void)
2694 for (i = 0; i < XMON_NUM_SPUS; i++) {
2695 if (!spu_info[i].spu)
2698 if (setjmp(bus_error_jmp) == 0) {
2699 catch_memory_errors = 1;
2702 spu = spu_info[i].spu;
2704 spu_info[i].saved_spu_runcntl_RW =
2705 in_be32(&spu->problem->spu_runcntl_RW);
2707 tmp = spu_mfc_sr1_get(spu);
2708 spu_info[i].saved_mfc_sr1_RW = tmp;
2710 tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
2711 spu_mfc_sr1_set(spu, tmp);
2716 spu_info[i].stopped_ok = 1;
2718 printf("Stopped spu %.2d (was %s)\n", i,
2719 spu_info[i].saved_spu_runcntl_RW ?
2720 "running" : "stopped");
2722 catch_memory_errors = 0;
2723 printf("*** Error stopping spu %.2d\n", i);
2725 catch_memory_errors = 0;
2729 static void restart_spus(void)
2734 for (i = 0; i < XMON_NUM_SPUS; i++) {
2735 if (!spu_info[i].spu)
2738 if (!spu_info[i].stopped_ok) {
2739 printf("*** Error, spu %d was not successfully stopped"
2740 ", not restarting\n", i);
2744 if (setjmp(bus_error_jmp) == 0) {
2745 catch_memory_errors = 1;
2748 spu = spu_info[i].spu;
2749 spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
2750 out_be32(&spu->problem->spu_runcntl_RW,
2751 spu_info[i].saved_spu_runcntl_RW);
2756 printf("Restarted spu %.2d\n", i);
2758 catch_memory_errors = 0;
2759 printf("*** Error restarting spu %.2d\n", i);
2761 catch_memory_errors = 0;
2765 #define DUMP_WIDTH 23
2766 #define DUMP_VALUE(format, field, value) \
2768 if (setjmp(bus_error_jmp) == 0) { \
2769 catch_memory_errors = 1; \
2771 printf(" %-*s = "format"\n", DUMP_WIDTH, \
2776 catch_memory_errors = 0; \
2777 printf(" %-*s = *** Error reading field.\n", \
2778 DUMP_WIDTH, #field); \
2780 catch_memory_errors = 0; \
2783 #define DUMP_FIELD(obj, format, field) \
2784 DUMP_VALUE(format, field, obj->field)
2786 static void dump_spu_fields(struct spu *spu)
2788 printf("Dumping spu fields at address %p:\n", spu);
2790 DUMP_FIELD(spu, "0x%x", number);
2791 DUMP_FIELD(spu, "%s", name);
2792 DUMP_FIELD(spu, "0x%lx", local_store_phys);
2793 DUMP_FIELD(spu, "0x%p", local_store);
2794 DUMP_FIELD(spu, "0x%lx", ls_size);
2795 DUMP_FIELD(spu, "0x%x", node);
2796 DUMP_FIELD(spu, "0x%lx", flags);
2797 DUMP_FIELD(spu, "0x%lx", dar);
2798 DUMP_FIELD(spu, "0x%lx", dsisr);
2799 DUMP_FIELD(spu, "%d", class_0_pending);
2800 DUMP_FIELD(spu, "0x%lx", irqs[0]);
2801 DUMP_FIELD(spu, "0x%lx", irqs[1]);
2802 DUMP_FIELD(spu, "0x%lx", irqs[2]);
2803 DUMP_FIELD(spu, "0x%x", slb_replace);
2804 DUMP_FIELD(spu, "%d", pid);
2805 DUMP_FIELD(spu, "%d", prio);
2806 DUMP_FIELD(spu, "0x%p", mm);
2807 DUMP_FIELD(spu, "0x%p", ctx);
2808 DUMP_FIELD(spu, "0x%p", rq);
2809 DUMP_FIELD(spu, "0x%p", timestamp);
2810 DUMP_FIELD(spu, "0x%lx", problem_phys);
2811 DUMP_FIELD(spu, "0x%p", problem);
2812 DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
2813 in_be32(&spu->problem->spu_runcntl_RW));
2814 DUMP_VALUE("0x%x", problem->spu_status_R,
2815 in_be32(&spu->problem->spu_status_R));
2816 DUMP_VALUE("0x%x", problem->spu_npc_RW,
2817 in_be32(&spu->problem->spu_npc_RW));
2818 DUMP_FIELD(spu, "0x%p", priv2);
2819 DUMP_FIELD(spu, "0x%p", pdata);
2823 spu_inst_dump(unsigned long adr, long count, int praddr)
2825 return generic_inst_dump(adr, count, praddr, print_insn_spu);
2828 static void dump_spu_ls(unsigned long num, int subcmd)
2830 unsigned long offset, addr, ls_addr;
2832 if (setjmp(bus_error_jmp) == 0) {
2833 catch_memory_errors = 1;
2835 ls_addr = (unsigned long)spu_info[num].spu->local_store;
2839 catch_memory_errors = 0;
2840 printf("*** Error: accessing spu info for spu %d\n", num);
2843 catch_memory_errors = 0;
2845 if (scanhex(&offset))
2846 addr = ls_addr + offset;
2848 addr = spu_info[num].dump_addr;
2850 if (addr >= ls_addr + LS_SIZE) {
2851 printf("*** Error: address outside of local store\n");
2857 addr += spu_inst_dump(addr, 16, 1);
2867 spu_info[num].dump_addr = addr;
2870 static int do_spu_cmd(void)
2872 static unsigned long num = 0;
2873 int cmd, subcmd = 0;
2885 if (isxdigit(subcmd) || subcmd == '\n')
2889 if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
2890 printf("*** Error: invalid spu number\n");
2896 dump_spu_fields(spu_info[num].spu);
2899 dump_spu_ls(num, subcmd);
2910 #else /* ! CONFIG_PPC_CELL */
2911 static int do_spu_cmd(void)