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, unsigned long, int);
159 extern void xmon_enter(void);
160 extern void xmon_leave(void);
162 extern long setjmp(long *);
163 extern void longjmp(long *, long);
164 extern void xmon_save_regs(struct pt_regs *);
168 #define REGS_PER_LINE 4
169 #define LAST_VOLATILE 13
172 #define REGS_PER_LINE 8
173 #define LAST_VOLATILE 12
176 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
178 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
179 || ('a' <= (c) && (c) <= 'f') \
180 || ('A' <= (c) && (c) <= 'F'))
181 #define isalnum(c) (('0' <= (c) && (c) <= '9') \
182 || ('a' <= (c) && (c) <= 'z') \
183 || ('A' <= (c) && (c) <= 'Z'))
184 #define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
186 static char *help_string = "\
188 b show breakpoints\n\
189 bd set data breakpoint\n\
190 bi set instruction breakpoint\n\
191 bc clear breakpoint\n"
194 c print cpus stopped in xmon\n\
195 c# try to switch to cpu number h (in hex)\n"
200 di dump instructions\n\
201 df dump float values\n\
202 dd dump double values\n\
203 dr dump stream of raw bytes\n\
204 e print exception information\n\
206 la lookup symbol+offset of specified address\n\
207 ls lookup address of specified symbol\n\
208 m examine/change memory\n\
209 mm move a block of memory\n\
210 ms set a block of memory\n\
211 md compare two blocks of memory\n\
212 ml locate a block of memory\n\
213 mz zero a block of memory\n\
214 mi show information about memory allocation\n\
215 p call a procedure\n\
218 #ifdef CONFIG_PPC_CELL
219 " ss stop execution on all spus\n\
220 sr restore execution on stopped spus\n\
221 sf # dump spu fields 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: '.');
2071 ppc_inst_dump(unsigned long adr, long count, int praddr)
2074 unsigned long first_adr;
2075 unsigned long inst, last_inst = 0;
2076 unsigned char val[4];
2079 for (first_adr = adr; count > 0; --count, adr += 4) {
2080 nr = mread(adr, val, 4);
2083 const char *x = fault_chars[fault_type];
2084 printf(REG" %s%s%s%s\n", adr, x, x, x, x);
2088 inst = GETWORD(val);
2089 if (adr > first_adr && inst == last_inst) {
2099 printf(REG" %.8x", adr, inst);
2101 print_insn_powerpc(inst, adr, 0); /* always returns 4 */
2104 return adr - first_adr;
2108 print_address(unsigned long addr)
2110 xmon_print_symbol(addr, "\t# ", "");
2115 * Memory operations - move, set, print differences
2117 static unsigned long mdest; /* destination address */
2118 static unsigned long msrc; /* source address */
2119 static unsigned long mval; /* byte value to set memory to */
2120 static unsigned long mcount; /* # bytes to affect */
2121 static unsigned long mdiffs; /* max # differences to print */
2126 scanhex((void *)&mdest);
2127 if( termch != '\n' )
2129 scanhex((void *)(cmd == 's'? &mval: &msrc));
2130 if( termch != '\n' )
2132 scanhex((void *)&mcount);
2135 memmove((void *)mdest, (void *)msrc, mcount);
2138 memset((void *)mdest, mval, mcount);
2141 if( termch != '\n' )
2143 scanhex((void *)&mdiffs);
2144 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2150 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2155 for( n = nb; n > 0; --n )
2156 if( *p1++ != *p2++ )
2157 if( ++prt <= maxpr )
2158 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2159 p1[-1], p2 - 1, p2[-1]);
2161 printf("Total of %d differences\n", prt);
2164 static unsigned mend;
2165 static unsigned mask;
2171 unsigned char val[4];
2174 scanhex((void *)&mdest);
2175 if (termch != '\n') {
2177 scanhex((void *)&mend);
2178 if (termch != '\n') {
2180 scanhex((void *)&mval);
2182 if (termch != '\n') termch = 0;
2183 scanhex((void *)&mask);
2187 for (a = mdest; a < mend; a += 4) {
2188 if (mread(a, val, 4) == 4
2189 && ((GETWORD(val) ^ mval) & mask) == 0) {
2190 printf("%.16x: %.16x\n", a, GETWORD(val));
2197 static unsigned long mskip = 0x1000;
2198 static unsigned long mlim = 0xffffffff;
2208 if (termch != '\n') termch = 0;
2210 if (termch != '\n') termch = 0;
2213 for (a = mdest; a < mlim; a += mskip) {
2214 ok = mread(a, &v, 1);
2216 printf("%.8x .. ", a);
2217 } else if (!ok && ook)
2218 printf("%.8x\n", a - mskip);
2224 printf("%.8x\n", a - mskip);
2229 unsigned long args[8];
2232 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2233 unsigned long, unsigned long, unsigned long,
2234 unsigned long, unsigned long, unsigned long);
2237 if (!scanhex(&adrs))
2241 for (i = 0; i < 8; ++i)
2243 for (i = 0; i < 8; ++i) {
2244 if (!scanhex(&args[i]) || termch == '\n')
2248 func = (callfunc_t) adrs;
2250 if (setjmp(bus_error_jmp) == 0) {
2251 catch_memory_errors = 1;
2253 ret = func(args[0], args[1], args[2], args[3],
2254 args[4], args[5], args[6], args[7]);
2256 printf("return value is %x\n", ret);
2258 printf("*** %x exception occurred\n", fault_except);
2260 catch_memory_errors = 0;
2263 /* Input scanning routines */
2274 while( c == ' ' || c == '\t' )
2280 static char *regnames[N_PTREGS] = {
2281 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2282 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2283 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2284 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2285 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2291 "trap", "dar", "dsisr", "res"
2295 scanhex(unsigned long *vp)
2302 /* parse register name */
2306 for (i = 0; i < sizeof(regname) - 1; ++i) {
2315 for (i = 0; i < N_PTREGS; ++i) {
2316 if (strcmp(regnames[i], regname) == 0) {
2317 if (xmon_regs == NULL) {
2318 printf("regs not available\n");
2321 *vp = ((unsigned long *)xmon_regs)[i];
2325 printf("invalid register name '%%%s'\n", regname);
2329 /* skip leading "0x" if any */
2343 } else if (c == '$') {
2345 for (i=0; i<63; i++) {
2355 if (setjmp(bus_error_jmp) == 0) {
2356 catch_memory_errors = 1;
2358 *vp = kallsyms_lookup_name(tmpstr);
2361 catch_memory_errors = 0;
2363 printf("unknown symbol '%s'\n", tmpstr);
2398 if( '0' <= c && c <= '9' )
2400 if( 'A' <= c && c <= 'F' )
2401 return c - ('A' - 10);
2402 if( 'a' <= c && c <= 'f' )
2403 return c - ('a' - 10);
2408 getstring(char *s, int size)
2419 } while( c != ' ' && c != '\t' && c != '\n' );
2424 static char line[256];
2425 static char *lineptr;
2436 if (lineptr == NULL || *lineptr == 0) {
2437 if (xmon_gets(line, sizeof(line)) == NULL) {
2447 take_input(char *str)
2456 int type = inchar();
2458 static char tmp[64];
2463 xmon_print_symbol(addr, ": ", "\n");
2468 if (setjmp(bus_error_jmp) == 0) {
2469 catch_memory_errors = 1;
2471 addr = kallsyms_lookup_name(tmp);
2473 printf("%s: %lx\n", tmp, addr);
2475 printf("Symbol '%s' not found.\n", tmp);
2478 catch_memory_errors = 0;
2485 /* Print an address in numeric and symbolic form (if possible) */
2486 static void xmon_print_symbol(unsigned long address, const char *mid,
2490 const char *name = NULL;
2491 unsigned long offset, size;
2493 printf(REG, address);
2494 if (setjmp(bus_error_jmp) == 0) {
2495 catch_memory_errors = 1;
2497 name = kallsyms_lookup(address, &size, &offset, &modname,
2500 /* wait a little while to see if we get a machine check */
2504 catch_memory_errors = 0;
2507 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2509 printf(" [%s]", modname);
2511 printf("%s", after);
2515 static void dump_slb(void)
2520 printf("SLB contents of cpu %x\n", smp_processor_id());
2522 for (i = 0; i < SLB_NUM_ENTRIES; i++) {
2523 asm volatile("slbmfee %0,%1" : "=r" (tmp) : "r" (i));
2524 printf("%02d %016lx ", i, tmp);
2526 asm volatile("slbmfev %0,%1" : "=r" (tmp) : "r" (i));
2527 printf("%016lx\n", tmp);
2531 static void dump_stab(void)
2534 unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2536 printf("Segment table contents of cpu %x\n", smp_processor_id());
2538 for (i = 0; i < PAGE_SIZE/16; i++) {
2545 printf("%03d %016lx ", i, a);
2546 printf("%016lx\n", b);
2551 void dump_segments(void)
2553 if (cpu_has_feature(CPU_FTR_SLB))
2560 #ifdef CONFIG_PPC_STD_MMU_32
2561 void dump_segments(void)
2566 for (i = 0; i < 16; ++i)
2567 printf(" %x", mfsrin(i));
2572 void xmon_init(int enable)
2576 __debugger_ipi = xmon_ipi;
2577 __debugger_bpt = xmon_bpt;
2578 __debugger_sstep = xmon_sstep;
2579 __debugger_iabr_match = xmon_iabr_match;
2580 __debugger_dabr_match = xmon_dabr_match;
2581 __debugger_fault_handler = xmon_fault_handler;
2584 __debugger_ipi = NULL;
2585 __debugger_bpt = NULL;
2586 __debugger_sstep = NULL;
2587 __debugger_iabr_match = NULL;
2588 __debugger_dabr_match = NULL;
2589 __debugger_fault_handler = NULL;
2594 #ifdef CONFIG_MAGIC_SYSRQ
2595 static void sysrq_handle_xmon(int key, struct tty_struct *tty)
2597 /* ensure xmon is enabled */
2599 debugger(get_irq_regs());
2602 static struct sysrq_key_op sysrq_xmon_op =
2604 .handler = sysrq_handle_xmon,
2606 .action_msg = "Entering xmon",
2609 static int __init setup_xmon_sysrq(void)
2611 register_sysrq_key('x', &sysrq_xmon_op);
2614 __initcall(setup_xmon_sysrq);
2615 #endif /* CONFIG_MAGIC_SYSRQ */
2617 int __initdata xmon_early, xmon_off;
2619 static int __init early_parse_xmon(char *p)
2621 if (!p || strncmp(p, "early", 5) == 0) {
2622 /* just "xmon" is equivalent to "xmon=early" */
2625 } else if (strncmp(p, "on", 2) == 0)
2627 else if (strncmp(p, "off", 3) == 0)
2629 else if (strncmp(p, "nobt", 4) == 0)
2630 xmon_no_auto_backtrace = 1;
2636 early_param("xmon", early_parse_xmon);
2638 void __init xmon_setup(void)
2640 #ifdef CONFIG_XMON_DEFAULT
2648 #ifdef CONFIG_PPC_CELL
2652 u64 saved_mfc_sr1_RW;
2653 u32 saved_spu_runcntl_RW;
2657 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
2659 static struct spu_info spu_info[XMON_NUM_SPUS];
2661 void xmon_register_spus(struct list_head *list)
2665 list_for_each_entry(spu, list, full_list) {
2666 if (spu->number >= XMON_NUM_SPUS) {
2671 spu_info[spu->number].spu = spu;
2672 spu_info[spu->number].stopped_ok = 0;
2676 static void stop_spus(void)
2682 for (i = 0; i < XMON_NUM_SPUS; i++) {
2683 if (!spu_info[i].spu)
2686 if (setjmp(bus_error_jmp) == 0) {
2687 catch_memory_errors = 1;
2690 spu = spu_info[i].spu;
2692 spu_info[i].saved_spu_runcntl_RW =
2693 in_be32(&spu->problem->spu_runcntl_RW);
2695 tmp = spu_mfc_sr1_get(spu);
2696 spu_info[i].saved_mfc_sr1_RW = tmp;
2698 tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
2699 spu_mfc_sr1_set(spu, tmp);
2704 spu_info[i].stopped_ok = 1;
2706 printf("Stopped spu %.2d (was %s)\n", i,
2707 spu_info[i].saved_spu_runcntl_RW ?
2708 "running" : "stopped");
2710 catch_memory_errors = 0;
2711 printf("*** Error stopping spu %.2d\n", i);
2713 catch_memory_errors = 0;
2717 static void restart_spus(void)
2722 for (i = 0; i < XMON_NUM_SPUS; i++) {
2723 if (!spu_info[i].spu)
2726 if (!spu_info[i].stopped_ok) {
2727 printf("*** Error, spu %d was not successfully stopped"
2728 ", not restarting\n", i);
2732 if (setjmp(bus_error_jmp) == 0) {
2733 catch_memory_errors = 1;
2736 spu = spu_info[i].spu;
2737 spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
2738 out_be32(&spu->problem->spu_runcntl_RW,
2739 spu_info[i].saved_spu_runcntl_RW);
2744 printf("Restarted spu %.2d\n", i);
2746 catch_memory_errors = 0;
2747 printf("*** Error restarting spu %.2d\n", i);
2749 catch_memory_errors = 0;
2753 #define DUMP_WIDTH 23
2754 #define DUMP_VALUE(format, field, value) \
2756 if (setjmp(bus_error_jmp) == 0) { \
2757 catch_memory_errors = 1; \
2759 printf(" %-*s = "format"\n", DUMP_WIDTH, \
2764 catch_memory_errors = 0; \
2765 printf(" %-*s = *** Error reading field.\n", \
2766 DUMP_WIDTH, #field); \
2768 catch_memory_errors = 0; \
2771 #define DUMP_FIELD(obj, format, field) \
2772 DUMP_VALUE(format, field, obj->field)
2774 static void dump_spu_fields(struct spu *spu)
2776 printf("Dumping spu fields at address %p:\n", spu);
2778 DUMP_FIELD(spu, "0x%x", number);
2779 DUMP_FIELD(spu, "%s", name);
2780 DUMP_FIELD(spu, "%s", devnode->full_name);
2781 DUMP_FIELD(spu, "0x%x", nid);
2782 DUMP_FIELD(spu, "0x%lx", local_store_phys);
2783 DUMP_FIELD(spu, "0x%p", local_store);
2784 DUMP_FIELD(spu, "0x%lx", ls_size);
2785 DUMP_FIELD(spu, "0x%x", node);
2786 DUMP_FIELD(spu, "0x%lx", flags);
2787 DUMP_FIELD(spu, "0x%lx", dar);
2788 DUMP_FIELD(spu, "0x%lx", dsisr);
2789 DUMP_FIELD(spu, "%d", class_0_pending);
2790 DUMP_FIELD(spu, "0x%lx", irqs[0]);
2791 DUMP_FIELD(spu, "0x%lx", irqs[1]);
2792 DUMP_FIELD(spu, "0x%lx", irqs[2]);
2793 DUMP_FIELD(spu, "0x%x", slb_replace);
2794 DUMP_FIELD(spu, "%d", pid);
2795 DUMP_FIELD(spu, "%d", prio);
2796 DUMP_FIELD(spu, "0x%p", mm);
2797 DUMP_FIELD(spu, "0x%p", ctx);
2798 DUMP_FIELD(spu, "0x%p", rq);
2799 DUMP_FIELD(spu, "0x%p", timestamp);
2800 DUMP_FIELD(spu, "0x%lx", problem_phys);
2801 DUMP_FIELD(spu, "0x%p", problem);
2802 DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
2803 in_be32(&spu->problem->spu_runcntl_RW));
2804 DUMP_VALUE("0x%x", problem->spu_status_R,
2805 in_be32(&spu->problem->spu_status_R));
2806 DUMP_VALUE("0x%x", problem->spu_npc_RW,
2807 in_be32(&spu->problem->spu_npc_RW));
2808 DUMP_FIELD(spu, "0x%p", priv1);
2811 DUMP_VALUE("0x%lx", priv1->mfc_sr1_RW,
2812 in_be64(&spu->priv1->mfc_sr1_RW));
2815 DUMP_FIELD(spu, "0x%p", priv2);
2818 static int do_spu_cmd(void)
2820 unsigned long num = 0;
2832 if (scanhex(&num) && num < XMON_NUM_SPUS && spu_info[num].spu)
2833 dump_spu_fields(spu_info[num].spu);
2835 printf("*** Error: invalid spu number\n");
2843 #else /* ! CONFIG_PPC_CELL */
2844 static int do_spu_cmd(void)