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/config.h>
12 #include <linux/errno.h>
13 #include <linux/sched.h>
14 #include <linux/smp.h>
16 #include <linux/reboot.h>
17 #include <linux/delay.h>
18 #include <linux/kallsyms.h>
19 #include <linux/cpumask.h>
20 #include <linux/module.h>
21 #include <linux/sysrq.h>
22 #include <linux/interrupt.h>
24 #include <asm/ptrace.h>
25 #include <asm/string.h>
27 #include <asm/machdep.h>
29 #include <asm/processor.h>
30 #include <asm/pgtable.h>
32 #include <asm/mmu_context.h>
33 #include <asm/cputable.h>
35 #include <asm/sstep.h>
39 #include <asm/hvcall.h>
45 #define scanhex xmon_scanhex
46 #define skipbl xmon_skipbl
49 cpumask_t cpus_in_xmon = CPU_MASK_NONE;
50 static unsigned long xmon_taken = 1;
51 static int xmon_owner;
53 #endif /* CONFIG_SMP */
55 static unsigned long in_xmon = 0;
57 static unsigned long adrs;
59 #define MAX_DUMP (128 * 1024)
60 static unsigned long ndump = 64;
61 static unsigned long nidump = 16;
62 static unsigned long ncsum = 4096;
64 static char tmpstr[128];
66 #define JMP_BUF_LEN 23
67 static long bus_error_jmp[JMP_BUF_LEN];
68 static int catch_memory_errors;
69 static long *xmon_fault_jmp[NR_CPUS];
70 #define setjmp xmon_setjmp
71 #define longjmp xmon_longjmp
73 /* Breakpoint stuff */
75 unsigned long address;
76 unsigned int instr[2];
82 /* Bits in bpt.enabled */
83 #define BP_IABR_TE 1 /* IABR translation enabled */
89 static struct bpt bpts[NBPTS];
90 static struct bpt dabr;
91 static struct bpt *iabr;
92 static unsigned bpinstr = 0x7fe00008; /* trap */
94 #define BP_NUM(bp) ((bp) - bpts + 1)
97 static int cmds(struct pt_regs *);
98 static int mread(unsigned long, void *, int);
99 static int mwrite(unsigned long, void *, int);
100 static int handle_fault(struct pt_regs *);
101 static void byterev(unsigned char *, int);
102 static void memex(void);
103 static int bsesc(void);
104 static void dump(void);
105 static void prdump(unsigned long, long);
106 static int ppc_inst_dump(unsigned long, long, int);
107 void print_address(unsigned long);
108 static void backtrace(struct pt_regs *);
109 static void excprint(struct pt_regs *);
110 static void prregs(struct pt_regs *);
111 static void memops(int);
112 static void memlocate(void);
113 static void memzcan(void);
114 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
116 int scanhex(unsigned long *valp);
117 static void scannl(void);
118 static int hexdigit(int);
119 void getstring(char *, int);
120 static void flush_input(void);
121 static int inchar(void);
122 static void take_input(char *);
123 static unsigned long read_spr(int);
124 static void write_spr(int, unsigned long);
125 static void super_regs(void);
126 static void remove_bpts(void);
127 static void insert_bpts(void);
128 static void remove_cpu_bpts(void);
129 static void insert_cpu_bpts(void);
130 static struct bpt *at_breakpoint(unsigned long pc);
131 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
132 static int do_step(struct pt_regs *);
133 static void bpt_cmds(void);
134 static void cacheflush(void);
135 static int cpu_cmd(void);
136 static void csum(void);
137 static void bootcmds(void);
138 static void proccall(void);
139 void dump_segments(void);
140 static void symbol_lookup(void);
141 static void xmon_print_symbol(unsigned long address, const char *mid,
143 static const char *getvecname(unsigned long vec);
145 extern int print_insn_powerpc(unsigned long, unsigned long, int);
147 extern void xmon_enter(void);
148 extern void xmon_leave(void);
150 extern long setjmp(long *);
151 extern void longjmp(long *, long);
152 extern void xmon_save_regs(struct pt_regs *);
156 #define REGS_PER_LINE 4
157 #define LAST_VOLATILE 13
160 #define REGS_PER_LINE 8
161 #define LAST_VOLATILE 12
164 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
166 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
167 || ('a' <= (c) && (c) <= 'f') \
168 || ('A' <= (c) && (c) <= 'F'))
169 #define isalnum(c) (('0' <= (c) && (c) <= '9') \
170 || ('a' <= (c) && (c) <= 'z') \
171 || ('A' <= (c) && (c) <= 'Z'))
172 #define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
174 static char *help_string = "\
176 b show breakpoints\n\
177 bd set data breakpoint\n\
178 bi set instruction breakpoint\n\
179 bc clear breakpoint\n"
182 c print cpus stopped in xmon\n\
183 c# try to switch to cpu number h (in hex)\n"
188 di dump instructions\n\
189 df dump float values\n\
190 dd dump double values\n\
191 dr dump stream of raw bytes\n\
192 e print exception information\n\
194 la lookup symbol+offset of specified address\n\
195 ls lookup address of specified symbol\n\
196 m examine/change memory\n\
197 mm move a block of memory\n\
198 ms set a block of memory\n\
199 md compare two blocks of memory\n\
200 ml locate a block of memory\n\
201 mz zero a block of memory\n\
202 mi show information about memory allocation\n\
203 p call a procedure\n\
206 S print special registers\n\
208 x exit monitor and recover\n\
209 X exit monitor and dont recover\n"
211 " u dump segment table or SLB\n"
213 #ifdef CONFIG_PPC_STD_MMU_32
214 " u dump segment registers\n"
221 static struct pt_regs *xmon_regs;
223 static inline void sync(void)
225 asm volatile("sync; isync");
228 static inline void store_inst(void *p)
230 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
233 static inline void cflush(void *p)
235 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
238 static inline void cinval(void *p)
240 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
244 * Disable surveillance (the service processor watchdog function)
245 * while we are in xmon.
246 * XXX we should re-enable it when we leave. :)
248 #define SURVEILLANCE_TOKEN 9000
250 static inline void disable_surveillance(void)
252 #ifdef CONFIG_PPC_PSERIES
253 /* Since this can't be a module, args should end up below 4GB. */
254 static struct rtas_args args;
257 * At this point we have got all the cpus we can into
258 * xmon, so there is hopefully no other cpu calling RTAS
259 * at the moment, even though we don't take rtas.lock.
260 * If we did try to take rtas.lock there would be a
261 * real possibility of deadlock.
263 args.token = rtas_token("set-indicator");
264 if (args.token == RTAS_UNKNOWN_SERVICE)
268 args.rets = &args.args[3];
269 args.args[0] = SURVEILLANCE_TOKEN;
272 enter_rtas(__pa(&args));
273 #endif /* CONFIG_PPC_PSERIES */
277 static int xmon_speaker;
279 static void get_output_lock(void)
281 int me = smp_processor_id() + 0x100;
282 int last_speaker = 0, prev;
285 if (xmon_speaker == me)
288 if (xmon_speaker == 0) {
289 last_speaker = cmpxchg(&xmon_speaker, 0, me);
290 if (last_speaker == 0)
294 while (xmon_speaker == last_speaker) {
297 /* hostile takeover */
298 prev = cmpxchg(&xmon_speaker, last_speaker, me);
299 if (prev == last_speaker)
306 static void release_output_lock(void)
312 static int xmon_core(struct pt_regs *regs, int fromipi)
317 long recurse_jmp[JMP_BUF_LEN];
318 unsigned long offset;
322 unsigned long timeout;
326 mtmsr(msr & ~MSR_EE); /* disable interrupts */
328 bp = in_breakpoint_table(regs->nip, &offset);
330 regs->nip = bp->address + offset;
331 atomic_dec(&bp->ref_count);
337 cpu = smp_processor_id();
338 if (cpu_isset(cpu, cpus_in_xmon)) {
341 printf("cpu 0x%x: Exception %lx %s in xmon, "
342 "returning to main loop\n",
343 cpu, regs->trap, getvecname(TRAP(regs)));
344 release_output_lock();
345 longjmp(xmon_fault_jmp[cpu], 1);
348 if (setjmp(recurse_jmp) != 0) {
349 if (!in_xmon || !xmon_gate) {
351 printf("xmon: WARNING: bad recursive fault "
352 "on cpu 0x%x\n", cpu);
353 release_output_lock();
356 secondary = !(xmon_taken && cpu == xmon_owner);
360 xmon_fault_jmp[cpu] = recurse_jmp;
361 cpu_set(cpu, cpus_in_xmon);
364 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
365 bp = at_breakpoint(regs->nip);
366 if (bp || (regs->msr & MSR_RI) == 0)
373 printf("cpu 0x%x stopped at breakpoint 0x%x (",
375 xmon_print_symbol(regs->nip, " ", ")\n");
377 if ((regs->msr & MSR_RI) == 0)
378 printf("WARNING: exception is not recoverable, "
380 release_output_lock();
385 while (secondary && !xmon_gate) {
389 secondary = test_and_set_bit(0, &in_xmon);
394 if (!secondary && !xmon_gate) {
395 /* we are the first cpu to come in */
396 /* interrupt other cpu(s) */
397 int ncpus = num_online_cpus();
402 smp_send_debugger_break(MSG_ALL_BUT_SELF);
403 /* wait for other cpus to come in */
404 for (timeout = 100000000; timeout != 0; --timeout) {
405 if (cpus_weight(cpus_in_xmon) >= ncpus)
411 disable_surveillance();
412 /* for breakpoint or single step, print the current instr. */
413 if (bp || TRAP(regs) == 0xd00)
414 ppc_inst_dump(regs->nip, 1, 0);
415 printf("enter ? for help\n");
424 if (cpu == xmon_owner) {
425 if (!test_and_set_bit(0, &xmon_taken)) {
430 while (cpu == xmon_owner)
444 /* have switched to some other cpu */
449 cpu_clear(cpu, cpus_in_xmon);
450 xmon_fault_jmp[cpu] = NULL;
452 /* UP is simple... */
454 printf("Exception %lx %s in xmon, returning to main loop\n",
455 regs->trap, getvecname(TRAP(regs)));
456 longjmp(xmon_fault_jmp[0], 1);
458 if (setjmp(recurse_jmp) == 0) {
459 xmon_fault_jmp[0] = recurse_jmp;
463 bp = at_breakpoint(regs->nip);
465 printf("Stopped at breakpoint %x (", BP_NUM(bp));
466 xmon_print_symbol(regs->nip, " ", ")\n");
468 if ((regs->msr & MSR_RI) == 0)
469 printf("WARNING: exception is not recoverable, "
472 disable_surveillance();
473 /* for breakpoint or single step, print the current instr. */
474 if (bp || TRAP(regs) == 0xd00)
475 ppc_inst_dump(regs->nip, 1, 0);
476 printf("enter ? for help\n");
485 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
486 bp = at_breakpoint(regs->nip);
488 int stepped = emulate_step(regs, bp->instr[0]);
490 regs->nip = (unsigned long) &bp->instr[0];
491 atomic_inc(&bp->ref_count);
492 } else if (stepped < 0) {
493 printf("Couldn't single-step %s instruction\n",
494 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
501 mtmsr(msr); /* restore interrupt enable */
506 int xmon(struct pt_regs *excp)
511 xmon_save_regs(®s);
514 return xmon_core(excp, 0);
519 xmon_irq(int irq, void *d, struct pt_regs *regs)
522 local_irq_save(flags);
523 printf("Keyboard interrupt\n");
525 local_irq_restore(flags);
529 static int xmon_bpt(struct pt_regs *regs)
532 unsigned long offset;
534 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
537 /* Are we at the trap at bp->instr[1] for some bp? */
538 bp = in_breakpoint_table(regs->nip, &offset);
539 if (bp != NULL && offset == 4) {
540 regs->nip = bp->address + 4;
541 atomic_dec(&bp->ref_count);
545 /* Are we at a breakpoint? */
546 bp = at_breakpoint(regs->nip);
555 static int xmon_sstep(struct pt_regs *regs)
563 static int xmon_dabr_match(struct pt_regs *regs)
565 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
567 if (dabr.enabled == 0)
573 static int xmon_iabr_match(struct pt_regs *regs)
575 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
583 static int xmon_ipi(struct pt_regs *regs)
586 if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
592 static int xmon_fault_handler(struct pt_regs *regs)
595 unsigned long offset;
597 if (in_xmon && catch_memory_errors)
598 handle_fault(regs); /* doesn't return */
600 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
601 bp = in_breakpoint_table(regs->nip, &offset);
603 regs->nip = bp->address + offset;
604 atomic_dec(&bp->ref_count);
611 static struct bpt *at_breakpoint(unsigned long pc)
617 for (i = 0; i < NBPTS; ++i, ++bp)
618 if (bp->enabled && pc == bp->address)
623 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
627 off = nip - (unsigned long) bpts;
628 if (off >= sizeof(bpts))
630 off %= sizeof(struct bpt);
631 if (off != offsetof(struct bpt, instr[0])
632 && off != offsetof(struct bpt, instr[1]))
634 *offp = off - offsetof(struct bpt, instr[0]);
635 return (struct bpt *) (nip - off);
638 static struct bpt *new_breakpoint(unsigned long a)
643 bp = at_breakpoint(a);
647 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
648 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
650 bp->instr[1] = bpinstr;
651 store_inst(&bp->instr[1]);
656 printf("Sorry, no free breakpoints. Please clear one first.\n");
660 static void insert_bpts(void)
666 for (i = 0; i < NBPTS; ++i, ++bp) {
667 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
669 if (mread(bp->address, &bp->instr[0], 4) != 4) {
670 printf("Couldn't read instruction at %lx, "
671 "disabling breakpoint there\n", bp->address);
675 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
676 printf("Breakpoint at %lx is on an mtmsrd or rfid "
677 "instruction, disabling it\n", bp->address);
681 store_inst(&bp->instr[0]);
682 if (bp->enabled & BP_IABR)
684 if (mwrite(bp->address, &bpinstr, 4) != 4) {
685 printf("Couldn't write instruction at %lx, "
686 "disabling breakpoint there\n", bp->address);
687 bp->enabled &= ~BP_TRAP;
690 store_inst((void *)bp->address);
694 static void insert_cpu_bpts(void)
697 set_dabr(dabr.address | (dabr.enabled & 7));
698 if (iabr && cpu_has_feature(CPU_FTR_IABR))
699 mtspr(SPRN_IABR, iabr->address
700 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
703 static void remove_bpts(void)
710 for (i = 0; i < NBPTS; ++i, ++bp) {
711 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
713 if (mread(bp->address, &instr, 4) == 4
715 && mwrite(bp->address, &bp->instr, 4) != 4)
716 printf("Couldn't remove breakpoint at %lx\n",
719 store_inst((void *)bp->address);
723 static void remove_cpu_bpts(void)
726 if (cpu_has_feature(CPU_FTR_IABR))
730 /* Command interpreting routine */
731 static char *last_cmd;
734 cmds(struct pt_regs *excp)
742 printf("%x:", smp_processor_id());
743 #endif /* CONFIG_SMP */
749 if (last_cmd == NULL)
751 take_input(last_cmd);
785 prregs(excp); /* print regs */
807 printf(" <no input ...>\n");
829 #ifdef CONFIG_PPC_STD_MMU
835 printf("Unrecognized command: ");
837 if (' ' < cmd && cmd <= '~')
840 printf("\\x%x", cmd);
842 } while (cmd != '\n');
843 printf(" (type ? for help)\n");
850 * Step a single instruction.
851 * Some instructions we emulate, others we execute with MSR_SE set.
853 static int do_step(struct pt_regs *regs)
858 /* check we are in 64-bit kernel mode, translation enabled */
859 if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
860 if (mread(regs->nip, &instr, 4) == 4) {
861 stepped = emulate_step(regs, instr);
863 printf("Couldn't single-step %s instruction\n",
864 (IS_RFID(instr)? "rfid": "mtmsrd"));
868 regs->trap = 0xd00 | (regs->trap & 1);
869 printf("stepped to ");
870 xmon_print_symbol(regs->nip, " ", "\n");
871 ppc_inst_dump(regs->nip, 1, 0);
880 static void bootcmds(void)
886 ppc_md.restart(NULL);
893 static int cpu_cmd(void)
900 if (!scanhex(&cpu)) {
901 /* print cpus waiting or in xmon */
902 printf("cpus stopped:");
904 for (cpu = 0; cpu < NR_CPUS; ++cpu) {
905 if (cpu_isset(cpu, cpus_in_xmon)) {
911 printf("-%x", cpu - 1);
916 printf("-%x", NR_CPUS - 1);
920 /* try to switch to cpu specified */
921 if (!cpu_isset(cpu, cpus_in_xmon)) {
922 printf("cpu 0x%x isn't in xmon\n", cpu);
929 while (!xmon_taken) {
930 if (--timeout == 0) {
931 if (test_and_set_bit(0, &xmon_taken))
933 /* take control back */
935 xmon_owner = smp_processor_id();
936 printf("cpu %u didn't take control\n", cpu);
944 #endif /* CONFIG_SMP */
947 static unsigned short fcstab[256] = {
948 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
949 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
950 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
951 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
952 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
953 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
954 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
955 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
956 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
957 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
958 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
959 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
960 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
961 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
962 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
963 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
964 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
965 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
966 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
967 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
968 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
969 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
970 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
971 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
972 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
973 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
974 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
975 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
976 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
977 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
978 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
979 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
982 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
993 if (!scanhex(&ncsum))
996 for (i = 0; i < ncsum; ++i) {
997 if (mread(adrs+i, &v, 1) == 0) {
998 printf("csum stopped at %x\n", adrs+i);
1003 printf("%x\n", fcs);
1007 * Check if this is a suitable place to put a breakpoint.
1009 static long check_bp_loc(unsigned long addr)
1014 if (!is_kernel_addr(addr)) {
1015 printf("Breakpoints may only be placed at kernel addresses\n");
1018 if (!mread(addr, &instr, sizeof(instr))) {
1019 printf("Can't read instruction at address %lx\n", addr);
1022 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1023 printf("Breakpoints may not be placed on mtmsrd or rfid "
1030 static char *breakpoint_help_string =
1031 "Breakpoint command usage:\n"
1032 "b show breakpoints\n"
1033 "b <addr> [cnt] set breakpoint at given instr addr\n"
1034 "bc clear all breakpoints\n"
1035 "bc <n/addr> clear breakpoint number n or at addr\n"
1036 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1037 "bd <addr> [cnt] set hardware data breakpoint\n"
1047 const char badaddr[] = "Only kernel addresses are permitted "
1048 "for breakpoints\n";
1053 case 'd': /* bd - hardware data breakpoint */
1058 else if (cmd == 'w')
1064 if (scanhex(&dabr.address)) {
1065 if (!is_kernel_addr(dabr.address)) {
1070 dabr.enabled = mode | BP_DABR;
1074 case 'i': /* bi - hardware instr breakpoint */
1075 if (!cpu_has_feature(CPU_FTR_IABR)) {
1076 printf("Hardware instruction breakpoint "
1077 "not supported on this cpu\n");
1081 iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1086 if (!check_bp_loc(a))
1088 bp = new_breakpoint(a);
1090 bp->enabled |= BP_IABR | BP_IABR_TE;
1098 /* clear all breakpoints */
1099 for (i = 0; i < NBPTS; ++i)
1100 bpts[i].enabled = 0;
1103 printf("All breakpoints cleared\n");
1107 if (a <= NBPTS && a >= 1) {
1108 /* assume a breakpoint number */
1109 bp = &bpts[a-1]; /* bp nums are 1 based */
1111 /* assume a breakpoint address */
1112 bp = at_breakpoint(a);
1114 printf("No breakpoint at %x\n", a);
1119 printf("Cleared breakpoint %x (", BP_NUM(bp));
1120 xmon_print_symbol(bp->address, " ", ")\n");
1128 printf(breakpoint_help_string);
1133 /* print all breakpoints */
1134 printf(" type address\n");
1136 printf(" data "REG" [", dabr.address);
1137 if (dabr.enabled & 1)
1139 if (dabr.enabled & 2)
1143 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1146 printf("%2x %s ", BP_NUM(bp),
1147 (bp->enabled & BP_IABR)? "inst": "trap");
1148 xmon_print_symbol(bp->address, " ", "\n");
1153 if (!check_bp_loc(a))
1155 bp = new_breakpoint(a);
1157 bp->enabled |= BP_TRAP;
1162 /* Very cheap human name for vector lookup. */
1164 const char *getvecname(unsigned long vec)
1169 case 0x100: ret = "(System Reset)"; break;
1170 case 0x200: ret = "(Machine Check)"; break;
1171 case 0x300: ret = "(Data Access)"; break;
1172 case 0x380: ret = "(Data SLB Access)"; break;
1173 case 0x400: ret = "(Instruction Access)"; break;
1174 case 0x480: ret = "(Instruction SLB Access)"; break;
1175 case 0x500: ret = "(Hardware Interrupt)"; break;
1176 case 0x600: ret = "(Alignment)"; break;
1177 case 0x700: ret = "(Program Check)"; break;
1178 case 0x800: ret = "(FPU Unavailable)"; break;
1179 case 0x900: ret = "(Decrementer)"; break;
1180 case 0xc00: ret = "(System Call)"; break;
1181 case 0xd00: ret = "(Single Step)"; break;
1182 case 0xf00: ret = "(Performance Monitor)"; break;
1183 case 0xf20: ret = "(Altivec Unavailable)"; break;
1184 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1190 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1191 unsigned long *endp)
1193 unsigned long size, offset;
1197 *startp = *endp = 0;
1200 if (setjmp(bus_error_jmp) == 0) {
1201 catch_memory_errors = 1;
1203 name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr);
1205 *startp = pc - offset;
1206 *endp = pc - offset + size;
1210 catch_memory_errors = 0;
1213 static int xmon_depth_to_print = 64;
1216 #define LRSAVE_OFFSET 0x10
1217 #define REG_FRAME_MARKER 0x7265677368657265ul /* "regshere" */
1218 #define MARKER_OFFSET 0x60
1219 #define REGS_OFFSET 0x70
1221 #define LRSAVE_OFFSET 4
1222 #define REG_FRAME_MARKER 0x72656773
1223 #define MARKER_OFFSET 8
1224 #define REGS_OFFSET 16
1227 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1231 unsigned long newsp;
1232 unsigned long marker;
1234 struct pt_regs regs;
1237 if (sp < PAGE_OFFSET) {
1239 printf("SP (%lx) is in userspace\n", sp);
1243 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1244 || !mread(sp, &newsp, sizeof(unsigned long))) {
1245 printf("Couldn't read stack frame at %lx\n", sp);
1250 * For the first stack frame, try to work out if
1251 * LR and/or the saved LR value in the bottommost
1252 * stack frame are valid.
1254 if ((pc | lr) != 0) {
1255 unsigned long fnstart, fnend;
1256 unsigned long nextip;
1259 get_function_bounds(pc, &fnstart, &fnend);
1262 mread(newsp + LRSAVE_OFFSET, &nextip,
1263 sizeof(unsigned long));
1265 if (lr < PAGE_OFFSET
1266 || (fnstart <= lr && lr < fnend))
1268 } else if (lr == nextip) {
1270 } else if (lr >= PAGE_OFFSET
1271 && !(fnstart <= lr && lr < fnend)) {
1272 printf("[link register ] ");
1273 xmon_print_symbol(lr, " ", "\n");
1276 printf("["REG"] ", sp);
1277 xmon_print_symbol(ip, " ", " (unreliable)\n");
1282 printf("["REG"] ", sp);
1283 xmon_print_symbol(ip, " ", "\n");
1286 /* Look for "regshere" marker to see if this is
1287 an exception frame. */
1288 if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1289 && marker == REG_FRAME_MARKER) {
1290 if (mread(sp + REGS_OFFSET, ®s, sizeof(regs))
1292 printf("Couldn't read registers at %lx\n",
1296 printf("--- Exception: %lx %s at ", regs.trap,
1297 getvecname(TRAP(®s)));
1300 xmon_print_symbol(pc, " ", "\n");
1307 } while (count++ < xmon_depth_to_print);
1310 static void backtrace(struct pt_regs *excp)
1315 xmon_show_stack(sp, 0, 0);
1317 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1321 static void print_bug_trap(struct pt_regs *regs)
1323 struct bug_entry *bug;
1326 if (regs->msr & MSR_PR)
1327 return; /* not in kernel */
1328 addr = regs->nip; /* address of trap instruction */
1329 if (addr < PAGE_OFFSET)
1331 bug = find_bug(regs->nip);
1334 if (bug->line & BUG_WARNING_TRAP)
1337 printf("kernel BUG in %s at %s:%d!\n",
1338 bug->function, bug->file, (unsigned int)bug->line);
1341 void excprint(struct pt_regs *fp)
1346 printf("cpu 0x%x: ", smp_processor_id());
1347 #endif /* CONFIG_SMP */
1350 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1352 xmon_print_symbol(fp->nip, ": ", "\n");
1354 printf(" lr: ", fp->link);
1355 xmon_print_symbol(fp->link, ": ", "\n");
1357 printf(" sp: %lx\n", fp->gpr[1]);
1358 printf(" msr: %lx\n", fp->msr);
1360 if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1361 printf(" dar: %lx\n", fp->dar);
1363 printf(" dsisr: %lx\n", fp->dsisr);
1366 printf(" current = 0x%lx\n", current);
1368 printf(" paca = 0x%lx\n", get_paca());
1371 printf(" pid = %ld, comm = %s\n",
1372 current->pid, current->comm);
1379 void prregs(struct pt_regs *fp)
1383 struct pt_regs regs;
1385 if (scanhex(&base)) {
1386 if (setjmp(bus_error_jmp) == 0) {
1387 catch_memory_errors = 1;
1389 regs = *(struct pt_regs *)base;
1393 catch_memory_errors = 0;
1394 printf("*** Error reading registers from "REG"\n",
1398 catch_memory_errors = 0;
1403 if (FULL_REGS(fp)) {
1404 for (n = 0; n < 16; ++n)
1405 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1406 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1408 for (n = 0; n < 7; ++n)
1409 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1410 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1413 for (n = 0; n < 32; ++n) {
1414 printf("R%.2d = %.8x%s", n, fp->gpr[n],
1415 (n & 3) == 3? "\n": " ");
1416 if (n == 12 && !FULL_REGS(fp)) {
1423 xmon_print_symbol(fp->nip, " ", "\n");
1425 xmon_print_symbol(fp->link, " ", "\n");
1426 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
1427 printf("ctr = "REG" xer = "REG" trap = %4lx\n",
1428 fp->ctr, fp->xer, fp->trap);
1430 if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1431 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1434 void cacheflush(void)
1437 unsigned long nflush;
1442 scanhex((void *)&adrs);
1447 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1448 if (setjmp(bus_error_jmp) == 0) {
1449 catch_memory_errors = 1;
1453 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1454 cflush((void *) adrs);
1456 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1457 cinval((void *) adrs);
1460 /* wait a little while to see if we get a machine check */
1463 catch_memory_errors = 0;
1469 unsigned int instrs[2];
1470 unsigned long (*code)(void);
1471 unsigned long ret = -1UL;
1473 unsigned long opd[3];
1475 opd[0] = (unsigned long)instrs;
1478 code = (unsigned long (*)(void)) opd;
1480 code = (unsigned long (*)(void)) instrs;
1483 /* mfspr r3,n; blr */
1484 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1485 instrs[1] = 0x4e800020;
1487 store_inst(instrs+1);
1489 if (setjmp(bus_error_jmp) == 0) {
1490 catch_memory_errors = 1;
1496 /* wait a little while to see if we get a machine check */
1505 write_spr(int n, unsigned long val)
1507 unsigned int instrs[2];
1508 unsigned long (*code)(unsigned long);
1510 unsigned long opd[3];
1512 opd[0] = (unsigned long)instrs;
1515 code = (unsigned long (*)(unsigned long)) opd;
1517 code = (unsigned long (*)(unsigned long)) instrs;
1520 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1521 instrs[1] = 0x4e800020;
1523 store_inst(instrs+1);
1525 if (setjmp(bus_error_jmp) == 0) {
1526 catch_memory_errors = 1;
1532 /* wait a little while to see if we get a machine check */
1538 static unsigned long regno;
1539 extern char exc_prolog;
1540 extern char dec_exc;
1542 void super_regs(void)
1546 #ifdef CONFIG_PPC_ISERIES
1547 struct paca_struct *ptrPaca = NULL;
1548 struct lppaca *ptrLpPaca = NULL;
1549 struct ItLpRegSave *ptrLpRegSave = NULL;
1554 unsigned long sp, toc;
1555 asm("mr %0,1" : "=r" (sp) :);
1556 asm("mr %0,2" : "=r" (toc) :);
1558 printf("msr = "REG" sprg0= "REG"\n",
1559 mfmsr(), mfspr(SPRN_SPRG0));
1560 printf("pvr = "REG" sprg1= "REG"\n",
1561 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
1562 printf("dec = "REG" sprg2= "REG"\n",
1563 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1564 printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1565 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
1566 #ifdef CONFIG_PPC_ISERIES
1567 // Dump out relevant Paca data areas.
1569 ptrPaca = get_paca();
1571 printf(" Local Processor Control Area (LpPaca): \n");
1572 ptrLpPaca = ptrPaca->lppaca_ptr;
1573 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1574 ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
1575 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1576 ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
1577 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
1579 printf(" Local Processor Register Save Area (LpRegSave): \n");
1580 ptrLpRegSave = ptrPaca->reg_save_ptr;
1581 printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n",
1582 ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
1583 printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n",
1584 ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
1585 printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n",
1586 ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
1595 val = read_spr(regno);
1597 write_spr(regno, val);
1600 printf("spr %lx = %lx\n", regno, read_spr(regno));
1607 * Stuff for reading and writing memory safely
1610 mread(unsigned long adrs, void *buf, int size)
1616 if (setjmp(bus_error_jmp) == 0) {
1617 catch_memory_errors = 1;
1623 *(u16 *)q = *(u16 *)p;
1626 *(u32 *)q = *(u32 *)p;
1629 *(u64 *)q = *(u64 *)p;
1632 for( ; n < size; ++n) {
1638 /* wait a little while to see if we get a machine check */
1642 catch_memory_errors = 0;
1647 mwrite(unsigned long adrs, void *buf, int size)
1653 if (setjmp(bus_error_jmp) == 0) {
1654 catch_memory_errors = 1;
1660 *(u16 *)p = *(u16 *)q;
1663 *(u32 *)p = *(u32 *)q;
1666 *(u64 *)p = *(u64 *)q;
1669 for ( ; n < size; ++n) {
1675 /* wait a little while to see if we get a machine check */
1679 printf("*** Error writing address %x\n", adrs + n);
1681 catch_memory_errors = 0;
1685 static int fault_type;
1686 static int fault_except;
1687 static char *fault_chars[] = { "--", "**", "##" };
1689 static int handle_fault(struct pt_regs *regs)
1691 fault_except = TRAP(regs);
1692 switch (TRAP(regs)) {
1704 longjmp(bus_error_jmp, 1);
1709 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1712 byterev(unsigned char *val, int size)
1718 SWAP(val[0], val[1], t);
1721 SWAP(val[0], val[3], t);
1722 SWAP(val[1], val[2], t);
1724 case 8: /* is there really any use for this? */
1725 SWAP(val[0], val[7], t);
1726 SWAP(val[1], val[6], t);
1727 SWAP(val[2], val[5], t);
1728 SWAP(val[3], val[4], t);
1736 static char *memex_help_string =
1737 "Memory examine command usage:\n"
1738 "m [addr] [flags] examine/change memory\n"
1739 " addr is optional. will start where left off.\n"
1740 " flags may include chars from this set:\n"
1741 " b modify by bytes (default)\n"
1742 " w modify by words (2 byte)\n"
1743 " l modify by longs (4 byte)\n"
1744 " d modify by doubleword (8 byte)\n"
1745 " r toggle reverse byte order mode\n"
1746 " n do not read memory (for i/o spaces)\n"
1747 " . ok to read (default)\n"
1748 "NOTE: flags are saved as defaults\n"
1751 static char *memex_subcmd_help_string =
1752 "Memory examine subcommands:\n"
1753 " hexval write this val to current location\n"
1754 " 'string' write chars from string to this location\n"
1755 " ' increment address\n"
1756 " ^ decrement address\n"
1757 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1758 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1759 " ` clear no-read flag\n"
1760 " ; stay at this addr\n"
1761 " v change to byte mode\n"
1762 " w change to word (2 byte) mode\n"
1763 " l change to long (4 byte) mode\n"
1764 " u change to doubleword (8 byte) mode\n"
1765 " m addr change current addr\n"
1766 " n toggle no-read flag\n"
1767 " r toggle byte reverse flag\n"
1768 " < count back up count bytes\n"
1769 " > count skip forward count bytes\n"
1770 " x exit this mode\n"
1776 int cmd, inc, i, nslash;
1778 unsigned char val[16];
1780 scanhex((void *)&adrs);
1783 printf(memex_help_string);
1789 while ((cmd = skipbl()) != '\n') {
1791 case 'b': size = 1; break;
1792 case 'w': size = 2; break;
1793 case 'l': size = 4; break;
1794 case 'd': size = 8; break;
1795 case 'r': brev = !brev; break;
1796 case 'n': mnoread = 1; break;
1797 case '.': mnoread = 0; break;
1806 n = mread(adrs, val, size);
1807 printf(REG"%c", adrs, brev? 'r': ' ');
1812 for (i = 0; i < n; ++i)
1813 printf("%.2x", val[i]);
1814 for (; i < size; ++i)
1815 printf("%s", fault_chars[fault_type]);
1822 for (i = 0; i < size; ++i)
1823 val[i] = n >> (i * 8);
1826 mwrite(adrs, val, size);
1839 else if( n == '\'' )
1841 for (i = 0; i < size; ++i)
1842 val[i] = n >> (i * 8);
1845 mwrite(adrs, val, size);
1882 adrs -= 1 << nslash;
1886 adrs += 1 << nslash;
1890 adrs += 1 << -nslash;
1894 adrs -= 1 << -nslash;
1897 scanhex((void *)&adrs);
1916 printf(memex_subcmd_help_string);
1931 case 'n': c = '\n'; break;
1932 case 'r': c = '\r'; break;
1933 case 'b': c = '\b'; break;
1934 case 't': c = '\t'; break;
1939 static void xmon_rawdump (unsigned long adrs, long ndump)
1942 unsigned char temp[16];
1944 for (n = ndump; n > 0;) {
1946 nr = mread(adrs, temp, r);
1948 for (m = 0; m < r; ++m) {
1950 printf("%.2x", temp[m]);
1952 printf("%s", fault_chars[fault_type]);
1961 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
1962 || ('a' <= (c) && (c) <= 'f') \
1963 || ('A' <= (c) && (c) <= 'F'))
1970 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
1972 scanhex((void *)&adrs);
1979 else if (nidump > MAX_DUMP)
1981 adrs += ppc_inst_dump(adrs, nidump, 1);
1983 } else if (c == 'r') {
1987 xmon_rawdump(adrs, ndump);
1994 else if (ndump > MAX_DUMP)
1996 prdump(adrs, ndump);
2003 prdump(unsigned long adrs, long ndump)
2005 long n, m, c, r, nr;
2006 unsigned char temp[16];
2008 for (n = ndump; n > 0;) {
2012 nr = mread(adrs, temp, r);
2014 for (m = 0; m < r; ++m) {
2015 if ((m & (sizeof(long) - 1)) == 0 && m > 0)
2018 printf("%.2x", temp[m]);
2020 printf("%s", fault_chars[fault_type]);
2022 for (; m < 16; ++m) {
2023 if ((m & (sizeof(long) - 1)) == 0)
2028 for (m = 0; m < r; ++m) {
2031 putchar(' ' <= c && c <= '~'? c: '.');
2045 ppc_inst_dump(unsigned long adr, long count, int praddr)
2048 unsigned long first_adr;
2049 unsigned long inst, last_inst = 0;
2050 unsigned char val[4];
2053 for (first_adr = adr; count > 0; --count, adr += 4) {
2054 nr = mread(adr, val, 4);
2057 const char *x = fault_chars[fault_type];
2058 printf(REG" %s%s%s%s\n", adr, x, x, x, x);
2062 inst = GETWORD(val);
2063 if (adr > first_adr && inst == last_inst) {
2073 printf(REG" %.8x", adr, inst);
2075 print_insn_powerpc(inst, adr, 0); /* always returns 4 */
2078 return adr - first_adr;
2082 print_address(unsigned long addr)
2084 xmon_print_symbol(addr, "\t# ", "");
2089 * Memory operations - move, set, print differences
2091 static unsigned long mdest; /* destination address */
2092 static unsigned long msrc; /* source address */
2093 static unsigned long mval; /* byte value to set memory to */
2094 static unsigned long mcount; /* # bytes to affect */
2095 static unsigned long mdiffs; /* max # differences to print */
2100 scanhex((void *)&mdest);
2101 if( termch != '\n' )
2103 scanhex((void *)(cmd == 's'? &mval: &msrc));
2104 if( termch != '\n' )
2106 scanhex((void *)&mcount);
2109 memmove((void *)mdest, (void *)msrc, mcount);
2112 memset((void *)mdest, mval, mcount);
2115 if( termch != '\n' )
2117 scanhex((void *)&mdiffs);
2118 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2124 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2129 for( n = nb; n > 0; --n )
2130 if( *p1++ != *p2++ )
2131 if( ++prt <= maxpr )
2132 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2133 p1[-1], p2 - 1, p2[-1]);
2135 printf("Total of %d differences\n", prt);
2138 static unsigned mend;
2139 static unsigned mask;
2145 unsigned char val[4];
2148 scanhex((void *)&mdest);
2149 if (termch != '\n') {
2151 scanhex((void *)&mend);
2152 if (termch != '\n') {
2154 scanhex((void *)&mval);
2156 if (termch != '\n') termch = 0;
2157 scanhex((void *)&mask);
2161 for (a = mdest; a < mend; a += 4) {
2162 if (mread(a, val, 4) == 4
2163 && ((GETWORD(val) ^ mval) & mask) == 0) {
2164 printf("%.16x: %.16x\n", a, GETWORD(val));
2171 static unsigned long mskip = 0x1000;
2172 static unsigned long mlim = 0xffffffff;
2182 if (termch != '\n') termch = 0;
2184 if (termch != '\n') termch = 0;
2187 for (a = mdest; a < mlim; a += mskip) {
2188 ok = mread(a, &v, 1);
2190 printf("%.8x .. ", a);
2191 } else if (!ok && ook)
2192 printf("%.8x\n", a - mskip);
2198 printf("%.8x\n", a - mskip);
2203 unsigned long args[8];
2206 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2207 unsigned long, unsigned long, unsigned long,
2208 unsigned long, unsigned long, unsigned long);
2211 if (!scanhex(&adrs))
2215 for (i = 0; i < 8; ++i)
2217 for (i = 0; i < 8; ++i) {
2218 if (!scanhex(&args[i]) || termch == '\n')
2222 func = (callfunc_t) adrs;
2224 if (setjmp(bus_error_jmp) == 0) {
2225 catch_memory_errors = 1;
2227 ret = func(args[0], args[1], args[2], args[3],
2228 args[4], args[5], args[6], args[7]);
2230 printf("return value is %x\n", ret);
2232 printf("*** %x exception occurred\n", fault_except);
2234 catch_memory_errors = 0;
2237 /* Input scanning routines */
2248 while( c == ' ' || c == '\t' )
2254 static char *regnames[N_PTREGS] = {
2255 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2256 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2257 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2258 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2259 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2265 "trap", "dar", "dsisr", "res"
2269 scanhex(unsigned long *vp)
2276 /* parse register name */
2280 for (i = 0; i < sizeof(regname) - 1; ++i) {
2289 for (i = 0; i < N_PTREGS; ++i) {
2290 if (strcmp(regnames[i], regname) == 0) {
2291 if (xmon_regs == NULL) {
2292 printf("regs not available\n");
2295 *vp = ((unsigned long *)xmon_regs)[i];
2299 printf("invalid register name '%%%s'\n", regname);
2303 /* skip leading "0x" if any */
2317 } else if (c == '$') {
2319 for (i=0; i<63; i++) {
2329 if (setjmp(bus_error_jmp) == 0) {
2330 catch_memory_errors = 1;
2332 *vp = kallsyms_lookup_name(tmpstr);
2335 catch_memory_errors = 0;
2337 printf("unknown symbol '%s'\n", tmpstr);
2372 if( '0' <= c && c <= '9' )
2374 if( 'A' <= c && c <= 'F' )
2375 return c - ('A' - 10);
2376 if( 'a' <= c && c <= 'f' )
2377 return c - ('a' - 10);
2382 getstring(char *s, int size)
2393 } while( c != ' ' && c != '\t' && c != '\n' );
2398 static char line[256];
2399 static char *lineptr;
2410 if (lineptr == NULL || *lineptr == 0) {
2411 if (xmon_gets(line, sizeof(line)) == NULL) {
2421 take_input(char *str)
2430 int type = inchar();
2432 static char tmp[64];
2437 xmon_print_symbol(addr, ": ", "\n");
2442 if (setjmp(bus_error_jmp) == 0) {
2443 catch_memory_errors = 1;
2445 addr = kallsyms_lookup_name(tmp);
2447 printf("%s: %lx\n", tmp, addr);
2449 printf("Symbol '%s' not found.\n", tmp);
2452 catch_memory_errors = 0;
2459 /* Print an address in numeric and symbolic form (if possible) */
2460 static void xmon_print_symbol(unsigned long address, const char *mid,
2464 const char *name = NULL;
2465 unsigned long offset, size;
2467 printf(REG, address);
2468 if (setjmp(bus_error_jmp) == 0) {
2469 catch_memory_errors = 1;
2471 name = kallsyms_lookup(address, &size, &offset, &modname,
2474 /* wait a little while to see if we get a machine check */
2478 catch_memory_errors = 0;
2481 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2483 printf(" [%s]", modname);
2485 printf("%s", after);
2489 static void dump_slb(void)
2494 printf("SLB contents of cpu %x\n", smp_processor_id());
2496 for (i = 0; i < SLB_NUM_ENTRIES; i++) {
2497 asm volatile("slbmfee %0,%1" : "=r" (tmp) : "r" (i));
2498 printf("%02d %016lx ", i, tmp);
2500 asm volatile("slbmfev %0,%1" : "=r" (tmp) : "r" (i));
2501 printf("%016lx\n", tmp);
2505 static void dump_stab(void)
2508 unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2510 printf("Segment table contents of cpu %x\n", smp_processor_id());
2512 for (i = 0; i < PAGE_SIZE/16; i++) {
2519 printf("%03d %016lx ", i, a);
2520 printf("%016lx\n", b);
2525 void dump_segments(void)
2527 if (cpu_has_feature(CPU_FTR_SLB))
2534 #ifdef CONFIG_PPC_STD_MMU_32
2535 void dump_segments(void)
2540 for (i = 0; i < 16; ++i)
2541 printf(" %x", mfsrin(i));
2546 void xmon_init(int enable)
2550 __debugger_ipi = xmon_ipi;
2551 __debugger_bpt = xmon_bpt;
2552 __debugger_sstep = xmon_sstep;
2553 __debugger_iabr_match = xmon_iabr_match;
2554 __debugger_dabr_match = xmon_dabr_match;
2555 __debugger_fault_handler = xmon_fault_handler;
2558 __debugger_ipi = NULL;
2559 __debugger_bpt = NULL;
2560 __debugger_sstep = NULL;
2561 __debugger_iabr_match = NULL;
2562 __debugger_dabr_match = NULL;
2563 __debugger_fault_handler = NULL;
2568 #ifdef CONFIG_MAGIC_SYSRQ
2569 static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs,
2570 struct tty_struct *tty)
2572 /* ensure xmon is enabled */
2577 static struct sysrq_key_op sysrq_xmon_op =
2579 .handler = sysrq_handle_xmon,
2581 .action_msg = "Entering xmon",
2584 static int __init setup_xmon_sysrq(void)
2586 register_sysrq_key('x', &sysrq_xmon_op);
2589 __initcall(setup_xmon_sysrq);
2590 #endif /* CONFIG_MAGIC_SYSRQ */