2 * Routines providing a simple monitor for use on the PowerMac.
4 * Copyright (C) 1996-2005 Paul Mackerras.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
11 #include <linux/errno.h>
12 #include <linux/sched.h>
13 #include <linux/smp.h>
15 #include <linux/reboot.h>
16 #include <linux/delay.h>
17 #include <linux/kallsyms.h>
18 #include <linux/cpumask.h>
19 #include <linux/module.h>
20 #include <linux/sysrq.h>
21 #include <linux/interrupt.h>
23 #include <asm/ptrace.h>
24 #include <asm/string.h>
26 #include <asm/machdep.h>
28 #include <asm/processor.h>
29 #include <asm/pgtable.h>
31 #include <asm/mmu_context.h>
32 #include <asm/cputable.h>
34 #include <asm/sstep.h>
38 #include <asm/hvcall.h>
44 #define scanhex xmon_scanhex
45 #define skipbl xmon_skipbl
48 cpumask_t cpus_in_xmon = CPU_MASK_NONE;
49 static unsigned long xmon_taken = 1;
50 static int xmon_owner;
52 #endif /* CONFIG_SMP */
54 static unsigned long in_xmon = 0;
56 static unsigned long adrs;
58 #define MAX_DUMP (128 * 1024)
59 static unsigned long ndump = 64;
60 static unsigned long nidump = 16;
61 static unsigned long ncsum = 4096;
63 static char tmpstr[128];
65 #define JMP_BUF_LEN 23
66 static long bus_error_jmp[JMP_BUF_LEN];
67 static int catch_memory_errors;
68 static long *xmon_fault_jmp[NR_CPUS];
69 #define setjmp xmon_setjmp
70 #define longjmp xmon_longjmp
72 /* Breakpoint stuff */
74 unsigned long address;
75 unsigned int instr[2];
81 /* Bits in bpt.enabled */
82 #define BP_IABR_TE 1 /* IABR translation enabled */
88 static struct bpt bpts[NBPTS];
89 static struct bpt dabr;
90 static struct bpt *iabr;
91 static unsigned bpinstr = 0x7fe00008; /* trap */
93 #define BP_NUM(bp) ((bp) - bpts + 1)
96 static int cmds(struct pt_regs *);
97 static int mread(unsigned long, void *, int);
98 static int mwrite(unsigned long, void *, int);
99 static int handle_fault(struct pt_regs *);
100 static void byterev(unsigned char *, int);
101 static void memex(void);
102 static int bsesc(void);
103 static void dump(void);
104 static void prdump(unsigned long, long);
105 static int ppc_inst_dump(unsigned long, long, int);
106 void print_address(unsigned long);
107 static void backtrace(struct pt_regs *);
108 static void excprint(struct pt_regs *);
109 static void prregs(struct pt_regs *);
110 static void memops(int);
111 static void memlocate(void);
112 static void memzcan(void);
113 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
115 int scanhex(unsigned long *valp);
116 static void scannl(void);
117 static int hexdigit(int);
118 void getstring(char *, int);
119 static void flush_input(void);
120 static int inchar(void);
121 static void take_input(char *);
122 static unsigned long read_spr(int);
123 static void write_spr(int, unsigned long);
124 static void super_regs(void);
125 static void remove_bpts(void);
126 static void insert_bpts(void);
127 static void remove_cpu_bpts(void);
128 static void insert_cpu_bpts(void);
129 static struct bpt *at_breakpoint(unsigned long pc);
130 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
131 static int do_step(struct pt_regs *);
132 static void bpt_cmds(void);
133 static void cacheflush(void);
134 static int cpu_cmd(void);
135 static void csum(void);
136 static void bootcmds(void);
137 static void proccall(void);
138 void dump_segments(void);
139 static void symbol_lookup(void);
140 static void xmon_show_stack(unsigned long sp, unsigned long lr,
142 static void xmon_print_symbol(unsigned long address, const char *mid,
144 static const char *getvecname(unsigned long vec);
146 int xmon_no_auto_backtrace;
148 extern int print_insn_powerpc(unsigned long, unsigned long, int);
150 extern void xmon_enter(void);
151 extern void xmon_leave(void);
153 extern long setjmp(long *);
154 extern void longjmp(long *, long);
155 extern void xmon_save_regs(struct pt_regs *);
159 #define REGS_PER_LINE 4
160 #define LAST_VOLATILE 13
163 #define REGS_PER_LINE 8
164 #define LAST_VOLATILE 12
167 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
169 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
170 || ('a' <= (c) && (c) <= 'f') \
171 || ('A' <= (c) && (c) <= 'F'))
172 #define isalnum(c) (('0' <= (c) && (c) <= '9') \
173 || ('a' <= (c) && (c) <= 'z') \
174 || ('A' <= (c) && (c) <= 'Z'))
175 #define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
177 static char *help_string = "\
179 b show breakpoints\n\
180 bd set data breakpoint\n\
181 bi set instruction breakpoint\n\
182 bc clear breakpoint\n"
185 c print cpus stopped in xmon\n\
186 c# try to switch to cpu number h (in hex)\n"
191 di dump instructions\n\
192 df dump float values\n\
193 dd dump double values\n\
194 dr dump stream of raw bytes\n\
195 e print exception information\n\
197 la lookup symbol+offset of specified address\n\
198 ls lookup address of specified symbol\n\
199 m examine/change memory\n\
200 mm move a block of memory\n\
201 ms set a block of memory\n\
202 md compare two blocks of memory\n\
203 ml locate a block of memory\n\
204 mz zero a block of memory\n\
205 mi show information about memory allocation\n\
206 p call a procedure\n\
209 S print special registers\n\
211 x exit monitor and recover\n\
212 X exit monitor and dont recover\n"
214 " u dump segment table or SLB\n"
216 #ifdef CONFIG_PPC_STD_MMU_32
217 " u dump segment registers\n"
224 static struct pt_regs *xmon_regs;
226 static inline void sync(void)
228 asm volatile("sync; isync");
231 static inline void store_inst(void *p)
233 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
236 static inline void cflush(void *p)
238 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
241 static inline void cinval(void *p)
243 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
247 * Disable surveillance (the service processor watchdog function)
248 * while we are in xmon.
249 * XXX we should re-enable it when we leave. :)
251 #define SURVEILLANCE_TOKEN 9000
253 static inline void disable_surveillance(void)
255 #ifdef CONFIG_PPC_PSERIES
256 /* Since this can't be a module, args should end up below 4GB. */
257 static struct rtas_args args;
260 * At this point we have got all the cpus we can into
261 * xmon, so there is hopefully no other cpu calling RTAS
262 * at the moment, even though we don't take rtas.lock.
263 * If we did try to take rtas.lock there would be a
264 * real possibility of deadlock.
266 args.token = rtas_token("set-indicator");
267 if (args.token == RTAS_UNKNOWN_SERVICE)
271 args.rets = &args.args[3];
272 args.args[0] = SURVEILLANCE_TOKEN;
275 enter_rtas(__pa(&args));
276 #endif /* CONFIG_PPC_PSERIES */
280 static int xmon_speaker;
282 static void get_output_lock(void)
284 int me = smp_processor_id() + 0x100;
285 int last_speaker = 0, prev;
288 if (xmon_speaker == me)
291 if (xmon_speaker == 0) {
292 last_speaker = cmpxchg(&xmon_speaker, 0, me);
293 if (last_speaker == 0)
297 while (xmon_speaker == last_speaker) {
300 /* hostile takeover */
301 prev = cmpxchg(&xmon_speaker, last_speaker, me);
302 if (prev == last_speaker)
309 static void release_output_lock(void)
315 static int xmon_core(struct pt_regs *regs, int fromipi)
320 long recurse_jmp[JMP_BUF_LEN];
321 unsigned long offset;
325 unsigned long timeout;
329 mtmsr(msr & ~MSR_EE); /* disable interrupts */
331 bp = in_breakpoint_table(regs->nip, &offset);
333 regs->nip = bp->address + offset;
334 atomic_dec(&bp->ref_count);
340 cpu = smp_processor_id();
341 if (cpu_isset(cpu, cpus_in_xmon)) {
344 printf("cpu 0x%x: Exception %lx %s in xmon, "
345 "returning to main loop\n",
346 cpu, regs->trap, getvecname(TRAP(regs)));
347 release_output_lock();
348 longjmp(xmon_fault_jmp[cpu], 1);
351 if (setjmp(recurse_jmp) != 0) {
352 if (!in_xmon || !xmon_gate) {
354 printf("xmon: WARNING: bad recursive fault "
355 "on cpu 0x%x\n", cpu);
356 release_output_lock();
359 secondary = !(xmon_taken && cpu == xmon_owner);
363 xmon_fault_jmp[cpu] = recurse_jmp;
364 cpu_set(cpu, cpus_in_xmon);
367 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
368 bp = at_breakpoint(regs->nip);
369 if (bp || (regs->msr & MSR_RI) == 0)
376 printf("cpu 0x%x stopped at breakpoint 0x%x (",
378 xmon_print_symbol(regs->nip, " ", ")\n");
380 if ((regs->msr & MSR_RI) == 0)
381 printf("WARNING: exception is not recoverable, "
383 release_output_lock();
388 while (secondary && !xmon_gate) {
392 secondary = test_and_set_bit(0, &in_xmon);
397 if (!secondary && !xmon_gate) {
398 /* we are the first cpu to come in */
399 /* interrupt other cpu(s) */
400 int ncpus = num_online_cpus();
405 smp_send_debugger_break(MSG_ALL_BUT_SELF);
406 /* wait for other cpus to come in */
407 for (timeout = 100000000; timeout != 0; --timeout) {
408 if (cpus_weight(cpus_in_xmon) >= ncpus)
414 disable_surveillance();
415 /* for breakpoint or single step, print the current instr. */
416 if (bp || TRAP(regs) == 0xd00)
417 ppc_inst_dump(regs->nip, 1, 0);
418 printf("enter ? for help\n");
427 if (cpu == xmon_owner) {
428 if (!test_and_set_bit(0, &xmon_taken)) {
433 while (cpu == xmon_owner)
447 /* have switched to some other cpu */
452 cpu_clear(cpu, cpus_in_xmon);
453 xmon_fault_jmp[cpu] = NULL;
455 /* UP is simple... */
457 printf("Exception %lx %s in xmon, returning to main loop\n",
458 regs->trap, getvecname(TRAP(regs)));
459 longjmp(xmon_fault_jmp[0], 1);
461 if (setjmp(recurse_jmp) == 0) {
462 xmon_fault_jmp[0] = recurse_jmp;
466 bp = at_breakpoint(regs->nip);
468 printf("Stopped at breakpoint %x (", BP_NUM(bp));
469 xmon_print_symbol(regs->nip, " ", ")\n");
471 if ((regs->msr & MSR_RI) == 0)
472 printf("WARNING: exception is not recoverable, "
475 disable_surveillance();
476 /* for breakpoint or single step, print the current instr. */
477 if (bp || TRAP(regs) == 0xd00)
478 ppc_inst_dump(regs->nip, 1, 0);
479 printf("enter ? for help\n");
488 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
489 bp = at_breakpoint(regs->nip);
491 int stepped = emulate_step(regs, bp->instr[0]);
493 regs->nip = (unsigned long) &bp->instr[0];
494 atomic_inc(&bp->ref_count);
495 } else if (stepped < 0) {
496 printf("Couldn't single-step %s instruction\n",
497 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
504 mtmsr(msr); /* restore interrupt enable */
509 int xmon(struct pt_regs *excp)
514 xmon_save_regs(®s);
517 return xmon_core(excp, 0);
522 xmon_irq(int irq, void *d, struct pt_regs *regs)
525 local_irq_save(flags);
526 printf("Keyboard interrupt\n");
528 local_irq_restore(flags);
532 static int xmon_bpt(struct pt_regs *regs)
535 unsigned long offset;
537 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
540 /* Are we at the trap at bp->instr[1] for some bp? */
541 bp = in_breakpoint_table(regs->nip, &offset);
542 if (bp != NULL && offset == 4) {
543 regs->nip = bp->address + 4;
544 atomic_dec(&bp->ref_count);
548 /* Are we at a breakpoint? */
549 bp = at_breakpoint(regs->nip);
558 static int xmon_sstep(struct pt_regs *regs)
566 static int xmon_dabr_match(struct pt_regs *regs)
568 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
570 if (dabr.enabled == 0)
576 static int xmon_iabr_match(struct pt_regs *regs)
578 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
586 static int xmon_ipi(struct pt_regs *regs)
589 if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
595 static int xmon_fault_handler(struct pt_regs *regs)
598 unsigned long offset;
600 if (in_xmon && catch_memory_errors)
601 handle_fault(regs); /* doesn't return */
603 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
604 bp = in_breakpoint_table(regs->nip, &offset);
606 regs->nip = bp->address + offset;
607 atomic_dec(&bp->ref_count);
614 static struct bpt *at_breakpoint(unsigned long pc)
620 for (i = 0; i < NBPTS; ++i, ++bp)
621 if (bp->enabled && pc == bp->address)
626 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
630 off = nip - (unsigned long) bpts;
631 if (off >= sizeof(bpts))
633 off %= sizeof(struct bpt);
634 if (off != offsetof(struct bpt, instr[0])
635 && off != offsetof(struct bpt, instr[1]))
637 *offp = off - offsetof(struct bpt, instr[0]);
638 return (struct bpt *) (nip - off);
641 static struct bpt *new_breakpoint(unsigned long a)
646 bp = at_breakpoint(a);
650 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
651 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
653 bp->instr[1] = bpinstr;
654 store_inst(&bp->instr[1]);
659 printf("Sorry, no free breakpoints. Please clear one first.\n");
663 static void insert_bpts(void)
669 for (i = 0; i < NBPTS; ++i, ++bp) {
670 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
672 if (mread(bp->address, &bp->instr[0], 4) != 4) {
673 printf("Couldn't read instruction at %lx, "
674 "disabling breakpoint there\n", bp->address);
678 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
679 printf("Breakpoint at %lx is on an mtmsrd or rfid "
680 "instruction, disabling it\n", bp->address);
684 store_inst(&bp->instr[0]);
685 if (bp->enabled & BP_IABR)
687 if (mwrite(bp->address, &bpinstr, 4) != 4) {
688 printf("Couldn't write instruction at %lx, "
689 "disabling breakpoint there\n", bp->address);
690 bp->enabled &= ~BP_TRAP;
693 store_inst((void *)bp->address);
697 static void insert_cpu_bpts(void)
700 set_dabr(dabr.address | (dabr.enabled & 7));
701 if (iabr && cpu_has_feature(CPU_FTR_IABR))
702 mtspr(SPRN_IABR, iabr->address
703 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
706 static void remove_bpts(void)
713 for (i = 0; i < NBPTS; ++i, ++bp) {
714 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
716 if (mread(bp->address, &instr, 4) == 4
718 && mwrite(bp->address, &bp->instr, 4) != 4)
719 printf("Couldn't remove breakpoint at %lx\n",
722 store_inst((void *)bp->address);
726 static void remove_cpu_bpts(void)
729 if (cpu_has_feature(CPU_FTR_IABR))
733 /* Command interpreting routine */
734 static char *last_cmd;
737 cmds(struct pt_regs *excp)
744 if (!xmon_no_auto_backtrace) {
745 xmon_no_auto_backtrace = 1;
746 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
751 printf("%x:", smp_processor_id());
752 #endif /* CONFIG_SMP */
758 if (last_cmd == NULL)
760 take_input(last_cmd);
794 prregs(excp); /* print regs */
816 printf(" <no input ...>\n");
838 #ifdef CONFIG_PPC_STD_MMU
844 printf("Unrecognized command: ");
846 if (' ' < cmd && cmd <= '~')
849 printf("\\x%x", cmd);
851 } while (cmd != '\n');
852 printf(" (type ? for help)\n");
859 * Step a single instruction.
860 * Some instructions we emulate, others we execute with MSR_SE set.
862 static int do_step(struct pt_regs *regs)
867 /* check we are in 64-bit kernel mode, translation enabled */
868 if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
869 if (mread(regs->nip, &instr, 4) == 4) {
870 stepped = emulate_step(regs, instr);
872 printf("Couldn't single-step %s instruction\n",
873 (IS_RFID(instr)? "rfid": "mtmsrd"));
877 regs->trap = 0xd00 | (regs->trap & 1);
878 printf("stepped to ");
879 xmon_print_symbol(regs->nip, " ", "\n");
880 ppc_inst_dump(regs->nip, 1, 0);
889 static void bootcmds(void)
895 ppc_md.restart(NULL);
902 static int cpu_cmd(void)
909 if (!scanhex(&cpu)) {
910 /* print cpus waiting or in xmon */
911 printf("cpus stopped:");
913 for (cpu = 0; cpu < NR_CPUS; ++cpu) {
914 if (cpu_isset(cpu, cpus_in_xmon)) {
920 printf("-%x", cpu - 1);
925 printf("-%x", NR_CPUS - 1);
929 /* try to switch to cpu specified */
930 if (!cpu_isset(cpu, cpus_in_xmon)) {
931 printf("cpu 0x%x isn't in xmon\n", cpu);
938 while (!xmon_taken) {
939 if (--timeout == 0) {
940 if (test_and_set_bit(0, &xmon_taken))
942 /* take control back */
944 xmon_owner = smp_processor_id();
945 printf("cpu %u didn't take control\n", cpu);
953 #endif /* CONFIG_SMP */
956 static unsigned short fcstab[256] = {
957 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
958 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
959 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
960 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
961 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
962 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
963 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
964 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
965 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
966 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
967 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
968 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
969 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
970 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
971 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
972 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
973 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
974 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
975 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
976 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
977 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
978 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
979 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
980 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
981 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
982 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
983 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
984 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
985 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
986 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
987 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
988 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
991 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1000 if (!scanhex(&adrs))
1002 if (!scanhex(&ncsum))
1005 for (i = 0; i < ncsum; ++i) {
1006 if (mread(adrs+i, &v, 1) == 0) {
1007 printf("csum stopped at %x\n", adrs+i);
1012 printf("%x\n", fcs);
1016 * Check if this is a suitable place to put a breakpoint.
1018 static long check_bp_loc(unsigned long addr)
1023 if (!is_kernel_addr(addr)) {
1024 printf("Breakpoints may only be placed at kernel addresses\n");
1027 if (!mread(addr, &instr, sizeof(instr))) {
1028 printf("Can't read instruction at address %lx\n", addr);
1031 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1032 printf("Breakpoints may not be placed on mtmsrd or rfid "
1039 static char *breakpoint_help_string =
1040 "Breakpoint command usage:\n"
1041 "b show breakpoints\n"
1042 "b <addr> [cnt] set breakpoint at given instr addr\n"
1043 "bc clear all breakpoints\n"
1044 "bc <n/addr> clear breakpoint number n or at addr\n"
1045 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1046 "bd <addr> [cnt] set hardware data breakpoint\n"
1056 const char badaddr[] = "Only kernel addresses are permitted "
1057 "for breakpoints\n";
1062 case 'd': /* bd - hardware data breakpoint */
1067 else if (cmd == 'w')
1073 if (scanhex(&dabr.address)) {
1074 if (!is_kernel_addr(dabr.address)) {
1079 dabr.enabled = mode | BP_DABR;
1083 case 'i': /* bi - hardware instr breakpoint */
1084 if (!cpu_has_feature(CPU_FTR_IABR)) {
1085 printf("Hardware instruction breakpoint "
1086 "not supported on this cpu\n");
1090 iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1095 if (!check_bp_loc(a))
1097 bp = new_breakpoint(a);
1099 bp->enabled |= BP_IABR | BP_IABR_TE;
1107 /* clear all breakpoints */
1108 for (i = 0; i < NBPTS; ++i)
1109 bpts[i].enabled = 0;
1112 printf("All breakpoints cleared\n");
1116 if (a <= NBPTS && a >= 1) {
1117 /* assume a breakpoint number */
1118 bp = &bpts[a-1]; /* bp nums are 1 based */
1120 /* assume a breakpoint address */
1121 bp = at_breakpoint(a);
1123 printf("No breakpoint at %x\n", a);
1128 printf("Cleared breakpoint %x (", BP_NUM(bp));
1129 xmon_print_symbol(bp->address, " ", ")\n");
1137 printf(breakpoint_help_string);
1142 /* print all breakpoints */
1143 printf(" type address\n");
1145 printf(" data "REG" [", dabr.address);
1146 if (dabr.enabled & 1)
1148 if (dabr.enabled & 2)
1152 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1155 printf("%2x %s ", BP_NUM(bp),
1156 (bp->enabled & BP_IABR)? "inst": "trap");
1157 xmon_print_symbol(bp->address, " ", "\n");
1162 if (!check_bp_loc(a))
1164 bp = new_breakpoint(a);
1166 bp->enabled |= BP_TRAP;
1171 /* Very cheap human name for vector lookup. */
1173 const char *getvecname(unsigned long vec)
1178 case 0x100: ret = "(System Reset)"; break;
1179 case 0x200: ret = "(Machine Check)"; break;
1180 case 0x300: ret = "(Data Access)"; break;
1181 case 0x380: ret = "(Data SLB Access)"; break;
1182 case 0x400: ret = "(Instruction Access)"; break;
1183 case 0x480: ret = "(Instruction SLB Access)"; break;
1184 case 0x500: ret = "(Hardware Interrupt)"; break;
1185 case 0x600: ret = "(Alignment)"; break;
1186 case 0x700: ret = "(Program Check)"; break;
1187 case 0x800: ret = "(FPU Unavailable)"; break;
1188 case 0x900: ret = "(Decrementer)"; break;
1189 case 0xc00: ret = "(System Call)"; break;
1190 case 0xd00: ret = "(Single Step)"; break;
1191 case 0xf00: ret = "(Performance Monitor)"; break;
1192 case 0xf20: ret = "(Altivec Unavailable)"; break;
1193 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1199 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1200 unsigned long *endp)
1202 unsigned long size, offset;
1206 *startp = *endp = 0;
1209 if (setjmp(bus_error_jmp) == 0) {
1210 catch_memory_errors = 1;
1212 name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr);
1214 *startp = pc - offset;
1215 *endp = pc - offset + size;
1219 catch_memory_errors = 0;
1222 static int xmon_depth_to_print = 64;
1225 #define LRSAVE_OFFSET 0x10
1226 #define REG_FRAME_MARKER 0x7265677368657265ul /* "regshere" */
1227 #define MARKER_OFFSET 0x60
1228 #define REGS_OFFSET 0x70
1230 #define LRSAVE_OFFSET 4
1231 #define REG_FRAME_MARKER 0x72656773
1232 #define MARKER_OFFSET 8
1233 #define REGS_OFFSET 16
1236 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1240 unsigned long newsp;
1241 unsigned long marker;
1243 struct pt_regs regs;
1246 if (sp < PAGE_OFFSET) {
1248 printf("SP (%lx) is in userspace\n", sp);
1252 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1253 || !mread(sp, &newsp, sizeof(unsigned long))) {
1254 printf("Couldn't read stack frame at %lx\n", sp);
1259 * For the first stack frame, try to work out if
1260 * LR and/or the saved LR value in the bottommost
1261 * stack frame are valid.
1263 if ((pc | lr) != 0) {
1264 unsigned long fnstart, fnend;
1265 unsigned long nextip;
1268 get_function_bounds(pc, &fnstart, &fnend);
1271 mread(newsp + LRSAVE_OFFSET, &nextip,
1272 sizeof(unsigned long));
1274 if (lr < PAGE_OFFSET
1275 || (fnstart <= lr && lr < fnend))
1277 } else if (lr == nextip) {
1279 } else if (lr >= PAGE_OFFSET
1280 && !(fnstart <= lr && lr < fnend)) {
1281 printf("[link register ] ");
1282 xmon_print_symbol(lr, " ", "\n");
1285 printf("["REG"] ", sp);
1286 xmon_print_symbol(ip, " ", " (unreliable)\n");
1291 printf("["REG"] ", sp);
1292 xmon_print_symbol(ip, " ", "\n");
1295 /* Look for "regshere" marker to see if this is
1296 an exception frame. */
1297 if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1298 && marker == REG_FRAME_MARKER) {
1299 if (mread(sp + REGS_OFFSET, ®s, sizeof(regs))
1301 printf("Couldn't read registers at %lx\n",
1305 printf("--- Exception: %lx %s at ", regs.trap,
1306 getvecname(TRAP(®s)));
1309 xmon_print_symbol(pc, " ", "\n");
1316 } while (count++ < xmon_depth_to_print);
1319 static void backtrace(struct pt_regs *excp)
1324 xmon_show_stack(sp, 0, 0);
1326 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1330 static void print_bug_trap(struct pt_regs *regs)
1332 struct bug_entry *bug;
1335 if (regs->msr & MSR_PR)
1336 return; /* not in kernel */
1337 addr = regs->nip; /* address of trap instruction */
1338 if (addr < PAGE_OFFSET)
1340 bug = find_bug(regs->nip);
1343 if (bug->line & BUG_WARNING_TRAP)
1346 printf("kernel BUG in %s at %s:%d!\n",
1347 bug->function, bug->file, (unsigned int)bug->line);
1350 void excprint(struct pt_regs *fp)
1355 printf("cpu 0x%x: ", smp_processor_id());
1356 #endif /* CONFIG_SMP */
1359 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1361 xmon_print_symbol(fp->nip, ": ", "\n");
1363 printf(" lr: ", fp->link);
1364 xmon_print_symbol(fp->link, ": ", "\n");
1366 printf(" sp: %lx\n", fp->gpr[1]);
1367 printf(" msr: %lx\n", fp->msr);
1369 if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1370 printf(" dar: %lx\n", fp->dar);
1372 printf(" dsisr: %lx\n", fp->dsisr);
1375 printf(" current = 0x%lx\n", current);
1377 printf(" paca = 0x%lx\n", get_paca());
1380 printf(" pid = %ld, comm = %s\n",
1381 current->pid, current->comm);
1388 void prregs(struct pt_regs *fp)
1392 struct pt_regs regs;
1394 if (scanhex(&base)) {
1395 if (setjmp(bus_error_jmp) == 0) {
1396 catch_memory_errors = 1;
1398 regs = *(struct pt_regs *)base;
1402 catch_memory_errors = 0;
1403 printf("*** Error reading registers from "REG"\n",
1407 catch_memory_errors = 0;
1412 if (FULL_REGS(fp)) {
1413 for (n = 0; n < 16; ++n)
1414 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1415 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1417 for (n = 0; n < 7; ++n)
1418 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1419 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1422 for (n = 0; n < 32; ++n) {
1423 printf("R%.2d = %.8x%s", n, fp->gpr[n],
1424 (n & 3) == 3? "\n": " ");
1425 if (n == 12 && !FULL_REGS(fp)) {
1432 xmon_print_symbol(fp->nip, " ", "\n");
1434 xmon_print_symbol(fp->link, " ", "\n");
1435 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
1436 printf("ctr = "REG" xer = "REG" trap = %4lx\n",
1437 fp->ctr, fp->xer, fp->trap);
1439 if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1440 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1443 void cacheflush(void)
1446 unsigned long nflush;
1451 scanhex((void *)&adrs);
1456 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1457 if (setjmp(bus_error_jmp) == 0) {
1458 catch_memory_errors = 1;
1462 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1463 cflush((void *) adrs);
1465 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1466 cinval((void *) adrs);
1469 /* wait a little while to see if we get a machine check */
1472 catch_memory_errors = 0;
1478 unsigned int instrs[2];
1479 unsigned long (*code)(void);
1480 unsigned long ret = -1UL;
1482 unsigned long opd[3];
1484 opd[0] = (unsigned long)instrs;
1487 code = (unsigned long (*)(void)) opd;
1489 code = (unsigned long (*)(void)) instrs;
1492 /* mfspr r3,n; blr */
1493 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1494 instrs[1] = 0x4e800020;
1496 store_inst(instrs+1);
1498 if (setjmp(bus_error_jmp) == 0) {
1499 catch_memory_errors = 1;
1505 /* wait a little while to see if we get a machine check */
1514 write_spr(int n, unsigned long val)
1516 unsigned int instrs[2];
1517 unsigned long (*code)(unsigned long);
1519 unsigned long opd[3];
1521 opd[0] = (unsigned long)instrs;
1524 code = (unsigned long (*)(unsigned long)) opd;
1526 code = (unsigned long (*)(unsigned long)) instrs;
1529 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1530 instrs[1] = 0x4e800020;
1532 store_inst(instrs+1);
1534 if (setjmp(bus_error_jmp) == 0) {
1535 catch_memory_errors = 1;
1541 /* wait a little while to see if we get a machine check */
1547 static unsigned long regno;
1548 extern char exc_prolog;
1549 extern char dec_exc;
1551 void super_regs(void)
1555 #ifdef CONFIG_PPC_ISERIES
1556 struct paca_struct *ptrPaca = NULL;
1557 struct lppaca *ptrLpPaca = NULL;
1558 struct ItLpRegSave *ptrLpRegSave = NULL;
1563 unsigned long sp, toc;
1564 asm("mr %0,1" : "=r" (sp) :);
1565 asm("mr %0,2" : "=r" (toc) :);
1567 printf("msr = "REG" sprg0= "REG"\n",
1568 mfmsr(), mfspr(SPRN_SPRG0));
1569 printf("pvr = "REG" sprg1= "REG"\n",
1570 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
1571 printf("dec = "REG" sprg2= "REG"\n",
1572 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1573 printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1574 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
1575 #ifdef CONFIG_PPC_ISERIES
1576 // Dump out relevant Paca data areas.
1578 ptrPaca = get_paca();
1580 printf(" Local Processor Control Area (LpPaca): \n");
1581 ptrLpPaca = ptrPaca->lppaca_ptr;
1582 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1583 ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
1584 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1585 ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
1586 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
1588 printf(" Local Processor Register Save Area (LpRegSave): \n");
1589 ptrLpRegSave = ptrPaca->reg_save_ptr;
1590 printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n",
1591 ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
1592 printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n",
1593 ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
1594 printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n",
1595 ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
1604 val = read_spr(regno);
1606 write_spr(regno, val);
1609 printf("spr %lx = %lx\n", regno, read_spr(regno));
1616 * Stuff for reading and writing memory safely
1619 mread(unsigned long adrs, void *buf, int size)
1625 if (setjmp(bus_error_jmp) == 0) {
1626 catch_memory_errors = 1;
1632 *(u16 *)q = *(u16 *)p;
1635 *(u32 *)q = *(u32 *)p;
1638 *(u64 *)q = *(u64 *)p;
1641 for( ; n < size; ++n) {
1647 /* wait a little while to see if we get a machine check */
1651 catch_memory_errors = 0;
1656 mwrite(unsigned long adrs, void *buf, int size)
1662 if (setjmp(bus_error_jmp) == 0) {
1663 catch_memory_errors = 1;
1669 *(u16 *)p = *(u16 *)q;
1672 *(u32 *)p = *(u32 *)q;
1675 *(u64 *)p = *(u64 *)q;
1678 for ( ; n < size; ++n) {
1684 /* wait a little while to see if we get a machine check */
1688 printf("*** Error writing address %x\n", adrs + n);
1690 catch_memory_errors = 0;
1694 static int fault_type;
1695 static int fault_except;
1696 static char *fault_chars[] = { "--", "**", "##" };
1698 static int handle_fault(struct pt_regs *regs)
1700 fault_except = TRAP(regs);
1701 switch (TRAP(regs)) {
1713 longjmp(bus_error_jmp, 1);
1718 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1721 byterev(unsigned char *val, int size)
1727 SWAP(val[0], val[1], t);
1730 SWAP(val[0], val[3], t);
1731 SWAP(val[1], val[2], t);
1733 case 8: /* is there really any use for this? */
1734 SWAP(val[0], val[7], t);
1735 SWAP(val[1], val[6], t);
1736 SWAP(val[2], val[5], t);
1737 SWAP(val[3], val[4], t);
1745 static char *memex_help_string =
1746 "Memory examine command usage:\n"
1747 "m [addr] [flags] examine/change memory\n"
1748 " addr is optional. will start where left off.\n"
1749 " flags may include chars from this set:\n"
1750 " b modify by bytes (default)\n"
1751 " w modify by words (2 byte)\n"
1752 " l modify by longs (4 byte)\n"
1753 " d modify by doubleword (8 byte)\n"
1754 " r toggle reverse byte order mode\n"
1755 " n do not read memory (for i/o spaces)\n"
1756 " . ok to read (default)\n"
1757 "NOTE: flags are saved as defaults\n"
1760 static char *memex_subcmd_help_string =
1761 "Memory examine subcommands:\n"
1762 " hexval write this val to current location\n"
1763 " 'string' write chars from string to this location\n"
1764 " ' increment address\n"
1765 " ^ decrement address\n"
1766 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1767 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1768 " ` clear no-read flag\n"
1769 " ; stay at this addr\n"
1770 " v change to byte mode\n"
1771 " w change to word (2 byte) mode\n"
1772 " l change to long (4 byte) mode\n"
1773 " u change to doubleword (8 byte) mode\n"
1774 " m addr change current addr\n"
1775 " n toggle no-read flag\n"
1776 " r toggle byte reverse flag\n"
1777 " < count back up count bytes\n"
1778 " > count skip forward count bytes\n"
1779 " x exit this mode\n"
1785 int cmd, inc, i, nslash;
1787 unsigned char val[16];
1789 scanhex((void *)&adrs);
1792 printf(memex_help_string);
1798 while ((cmd = skipbl()) != '\n') {
1800 case 'b': size = 1; break;
1801 case 'w': size = 2; break;
1802 case 'l': size = 4; break;
1803 case 'd': size = 8; break;
1804 case 'r': brev = !brev; break;
1805 case 'n': mnoread = 1; break;
1806 case '.': mnoread = 0; break;
1815 n = mread(adrs, val, size);
1816 printf(REG"%c", adrs, brev? 'r': ' ');
1821 for (i = 0; i < n; ++i)
1822 printf("%.2x", val[i]);
1823 for (; i < size; ++i)
1824 printf("%s", fault_chars[fault_type]);
1831 for (i = 0; i < size; ++i)
1832 val[i] = n >> (i * 8);
1835 mwrite(adrs, val, size);
1848 else if( n == '\'' )
1850 for (i = 0; i < size; ++i)
1851 val[i] = n >> (i * 8);
1854 mwrite(adrs, val, size);
1891 adrs -= 1 << nslash;
1895 adrs += 1 << nslash;
1899 adrs += 1 << -nslash;
1903 adrs -= 1 << -nslash;
1906 scanhex((void *)&adrs);
1925 printf(memex_subcmd_help_string);
1940 case 'n': c = '\n'; break;
1941 case 'r': c = '\r'; break;
1942 case 'b': c = '\b'; break;
1943 case 't': c = '\t'; break;
1948 static void xmon_rawdump (unsigned long adrs, long ndump)
1951 unsigned char temp[16];
1953 for (n = ndump; n > 0;) {
1955 nr = mread(adrs, temp, r);
1957 for (m = 0; m < r; ++m) {
1959 printf("%.2x", temp[m]);
1961 printf("%s", fault_chars[fault_type]);
1970 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
1971 || ('a' <= (c) && (c) <= 'f') \
1972 || ('A' <= (c) && (c) <= 'F'))
1979 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
1981 scanhex((void *)&adrs);
1988 else if (nidump > MAX_DUMP)
1990 adrs += ppc_inst_dump(adrs, nidump, 1);
1992 } else if (c == 'r') {
1996 xmon_rawdump(adrs, ndump);
2003 else if (ndump > MAX_DUMP)
2005 prdump(adrs, ndump);
2012 prdump(unsigned long adrs, long ndump)
2014 long n, m, c, r, nr;
2015 unsigned char temp[16];
2017 for (n = ndump; n > 0;) {
2021 nr = mread(adrs, temp, r);
2023 for (m = 0; m < r; ++m) {
2024 if ((m & (sizeof(long) - 1)) == 0 && m > 0)
2027 printf("%.2x", temp[m]);
2029 printf("%s", fault_chars[fault_type]);
2031 for (; m < 16; ++m) {
2032 if ((m & (sizeof(long) - 1)) == 0)
2037 for (m = 0; m < r; ++m) {
2040 putchar(' ' <= c && c <= '~'? c: '.');
2054 ppc_inst_dump(unsigned long adr, long count, int praddr)
2057 unsigned long first_adr;
2058 unsigned long inst, last_inst = 0;
2059 unsigned char val[4];
2062 for (first_adr = adr; count > 0; --count, adr += 4) {
2063 nr = mread(adr, val, 4);
2066 const char *x = fault_chars[fault_type];
2067 printf(REG" %s%s%s%s\n", adr, x, x, x, x);
2071 inst = GETWORD(val);
2072 if (adr > first_adr && inst == last_inst) {
2082 printf(REG" %.8x", adr, inst);
2084 print_insn_powerpc(inst, adr, 0); /* always returns 4 */
2087 return adr - first_adr;
2091 print_address(unsigned long addr)
2093 xmon_print_symbol(addr, "\t# ", "");
2098 * Memory operations - move, set, print differences
2100 static unsigned long mdest; /* destination address */
2101 static unsigned long msrc; /* source address */
2102 static unsigned long mval; /* byte value to set memory to */
2103 static unsigned long mcount; /* # bytes to affect */
2104 static unsigned long mdiffs; /* max # differences to print */
2109 scanhex((void *)&mdest);
2110 if( termch != '\n' )
2112 scanhex((void *)(cmd == 's'? &mval: &msrc));
2113 if( termch != '\n' )
2115 scanhex((void *)&mcount);
2118 memmove((void *)mdest, (void *)msrc, mcount);
2121 memset((void *)mdest, mval, mcount);
2124 if( termch != '\n' )
2126 scanhex((void *)&mdiffs);
2127 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2133 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2138 for( n = nb; n > 0; --n )
2139 if( *p1++ != *p2++ )
2140 if( ++prt <= maxpr )
2141 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2142 p1[-1], p2 - 1, p2[-1]);
2144 printf("Total of %d differences\n", prt);
2147 static unsigned mend;
2148 static unsigned mask;
2154 unsigned char val[4];
2157 scanhex((void *)&mdest);
2158 if (termch != '\n') {
2160 scanhex((void *)&mend);
2161 if (termch != '\n') {
2163 scanhex((void *)&mval);
2165 if (termch != '\n') termch = 0;
2166 scanhex((void *)&mask);
2170 for (a = mdest; a < mend; a += 4) {
2171 if (mread(a, val, 4) == 4
2172 && ((GETWORD(val) ^ mval) & mask) == 0) {
2173 printf("%.16x: %.16x\n", a, GETWORD(val));
2180 static unsigned long mskip = 0x1000;
2181 static unsigned long mlim = 0xffffffff;
2191 if (termch != '\n') termch = 0;
2193 if (termch != '\n') termch = 0;
2196 for (a = mdest; a < mlim; a += mskip) {
2197 ok = mread(a, &v, 1);
2199 printf("%.8x .. ", a);
2200 } else if (!ok && ook)
2201 printf("%.8x\n", a - mskip);
2207 printf("%.8x\n", a - mskip);
2212 unsigned long args[8];
2215 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2216 unsigned long, unsigned long, unsigned long,
2217 unsigned long, unsigned long, unsigned long);
2220 if (!scanhex(&adrs))
2224 for (i = 0; i < 8; ++i)
2226 for (i = 0; i < 8; ++i) {
2227 if (!scanhex(&args[i]) || termch == '\n')
2231 func = (callfunc_t) adrs;
2233 if (setjmp(bus_error_jmp) == 0) {
2234 catch_memory_errors = 1;
2236 ret = func(args[0], args[1], args[2], args[3],
2237 args[4], args[5], args[6], args[7]);
2239 printf("return value is %x\n", ret);
2241 printf("*** %x exception occurred\n", fault_except);
2243 catch_memory_errors = 0;
2246 /* Input scanning routines */
2257 while( c == ' ' || c == '\t' )
2263 static char *regnames[N_PTREGS] = {
2264 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2265 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2266 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2267 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2268 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2274 "trap", "dar", "dsisr", "res"
2278 scanhex(unsigned long *vp)
2285 /* parse register name */
2289 for (i = 0; i < sizeof(regname) - 1; ++i) {
2298 for (i = 0; i < N_PTREGS; ++i) {
2299 if (strcmp(regnames[i], regname) == 0) {
2300 if (xmon_regs == NULL) {
2301 printf("regs not available\n");
2304 *vp = ((unsigned long *)xmon_regs)[i];
2308 printf("invalid register name '%%%s'\n", regname);
2312 /* skip leading "0x" if any */
2326 } else if (c == '$') {
2328 for (i=0; i<63; i++) {
2338 if (setjmp(bus_error_jmp) == 0) {
2339 catch_memory_errors = 1;
2341 *vp = kallsyms_lookup_name(tmpstr);
2344 catch_memory_errors = 0;
2346 printf("unknown symbol '%s'\n", tmpstr);
2381 if( '0' <= c && c <= '9' )
2383 if( 'A' <= c && c <= 'F' )
2384 return c - ('A' - 10);
2385 if( 'a' <= c && c <= 'f' )
2386 return c - ('a' - 10);
2391 getstring(char *s, int size)
2402 } while( c != ' ' && c != '\t' && c != '\n' );
2407 static char line[256];
2408 static char *lineptr;
2419 if (lineptr == NULL || *lineptr == 0) {
2420 if (xmon_gets(line, sizeof(line)) == NULL) {
2430 take_input(char *str)
2439 int type = inchar();
2441 static char tmp[64];
2446 xmon_print_symbol(addr, ": ", "\n");
2451 if (setjmp(bus_error_jmp) == 0) {
2452 catch_memory_errors = 1;
2454 addr = kallsyms_lookup_name(tmp);
2456 printf("%s: %lx\n", tmp, addr);
2458 printf("Symbol '%s' not found.\n", tmp);
2461 catch_memory_errors = 0;
2468 /* Print an address in numeric and symbolic form (if possible) */
2469 static void xmon_print_symbol(unsigned long address, const char *mid,
2473 const char *name = NULL;
2474 unsigned long offset, size;
2476 printf(REG, address);
2477 if (setjmp(bus_error_jmp) == 0) {
2478 catch_memory_errors = 1;
2480 name = kallsyms_lookup(address, &size, &offset, &modname,
2483 /* wait a little while to see if we get a machine check */
2487 catch_memory_errors = 0;
2490 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2492 printf(" [%s]", modname);
2494 printf("%s", after);
2498 static void dump_slb(void)
2503 printf("SLB contents of cpu %x\n", smp_processor_id());
2505 for (i = 0; i < SLB_NUM_ENTRIES; i++) {
2506 asm volatile("slbmfee %0,%1" : "=r" (tmp) : "r" (i));
2507 printf("%02d %016lx ", i, tmp);
2509 asm volatile("slbmfev %0,%1" : "=r" (tmp) : "r" (i));
2510 printf("%016lx\n", tmp);
2514 static void dump_stab(void)
2517 unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2519 printf("Segment table contents of cpu %x\n", smp_processor_id());
2521 for (i = 0; i < PAGE_SIZE/16; i++) {
2528 printf("%03d %016lx ", i, a);
2529 printf("%016lx\n", b);
2534 void dump_segments(void)
2536 if (cpu_has_feature(CPU_FTR_SLB))
2543 #ifdef CONFIG_PPC_STD_MMU_32
2544 void dump_segments(void)
2549 for (i = 0; i < 16; ++i)
2550 printf(" %x", mfsrin(i));
2555 void xmon_init(int enable)
2559 __debugger_ipi = xmon_ipi;
2560 __debugger_bpt = xmon_bpt;
2561 __debugger_sstep = xmon_sstep;
2562 __debugger_iabr_match = xmon_iabr_match;
2563 __debugger_dabr_match = xmon_dabr_match;
2564 __debugger_fault_handler = xmon_fault_handler;
2567 __debugger_ipi = NULL;
2568 __debugger_bpt = NULL;
2569 __debugger_sstep = NULL;
2570 __debugger_iabr_match = NULL;
2571 __debugger_dabr_match = NULL;
2572 __debugger_fault_handler = NULL;
2577 #ifdef CONFIG_MAGIC_SYSRQ
2578 static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs,
2579 struct tty_struct *tty)
2581 /* ensure xmon is enabled */
2586 static struct sysrq_key_op sysrq_xmon_op =
2588 .handler = sysrq_handle_xmon,
2590 .action_msg = "Entering xmon",
2593 static int __init setup_xmon_sysrq(void)
2595 register_sysrq_key('x', &sysrq_xmon_op);
2598 __initcall(setup_xmon_sysrq);
2599 #endif /* CONFIG_MAGIC_SYSRQ */