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>
23 #include <asm/ptrace.h>
24 #include <asm/string.h>
26 #include <asm/machdep.h>
28 #ifdef CONFIG_PMAC_BACKLIGHT
29 #include <asm/backlight.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>
41 #include <asm/hvcall.h>
47 #define scanhex xmon_scanhex
48 #define skipbl xmon_skipbl
51 cpumask_t cpus_in_xmon = CPU_MASK_NONE;
52 static unsigned long xmon_taken = 1;
53 static int xmon_owner;
55 #endif /* CONFIG_SMP */
57 static unsigned long in_xmon = 0;
59 static unsigned long adrs;
61 #define MAX_DUMP (128 * 1024)
62 static unsigned long ndump = 64;
63 static unsigned long nidump = 16;
64 static unsigned long ncsum = 4096;
66 static char tmpstr[128];
68 #define JMP_BUF_LEN 23
69 static long bus_error_jmp[JMP_BUF_LEN];
70 static int catch_memory_errors;
71 static long *xmon_fault_jmp[NR_CPUS];
72 #define setjmp xmon_setjmp
73 #define longjmp xmon_longjmp
75 /* Breakpoint stuff */
77 unsigned long address;
78 unsigned int instr[2];
84 /* Bits in bpt.enabled */
85 #define BP_IABR_TE 1 /* IABR translation enabled */
91 static struct bpt bpts[NBPTS];
92 static struct bpt dabr;
93 static struct bpt *iabr;
94 static unsigned bpinstr = 0x7fe00008; /* trap */
96 #define BP_NUM(bp) ((bp) - bpts + 1)
99 static int cmds(struct pt_regs *);
100 static int mread(unsigned long, void *, int);
101 static int mwrite(unsigned long, void *, int);
102 static int handle_fault(struct pt_regs *);
103 static void byterev(unsigned char *, int);
104 static void memex(void);
105 static int bsesc(void);
106 static void dump(void);
107 static void prdump(unsigned long, long);
108 static int ppc_inst_dump(unsigned long, long, int);
109 void print_address(unsigned long);
110 static void backtrace(struct pt_regs *);
111 static void excprint(struct pt_regs *);
112 static void prregs(struct pt_regs *);
113 static void memops(int);
114 static void memlocate(void);
115 static void memzcan(void);
116 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
118 int scanhex(unsigned long *valp);
119 static void scannl(void);
120 static int hexdigit(int);
121 void getstring(char *, int);
122 static void flush_input(void);
123 static int inchar(void);
124 static void take_input(char *);
125 static unsigned long read_spr(int);
126 static void write_spr(int, unsigned long);
127 static void super_regs(void);
128 static void remove_bpts(void);
129 static void insert_bpts(void);
130 static void remove_cpu_bpts(void);
131 static void insert_cpu_bpts(void);
132 static struct bpt *at_breakpoint(unsigned long pc);
133 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
134 static int do_step(struct pt_regs *);
135 static void bpt_cmds(void);
136 static void cacheflush(void);
137 static int cpu_cmd(void);
138 static void csum(void);
139 static void bootcmds(void);
140 static void proccall(void);
141 void dump_segments(void);
142 static void symbol_lookup(void);
143 static void xmon_print_symbol(unsigned long address, const char *mid,
145 static const char *getvecname(unsigned long vec);
147 extern int print_insn_powerpc(unsigned long, unsigned long, int);
149 extern void xmon_enter(void);
150 extern void xmon_leave(void);
152 extern long setjmp(long *);
153 extern void longjmp(long *, long);
154 extern void xmon_save_regs(struct pt_regs *);
158 #define REGS_PER_LINE 4
159 #define LAST_VOLATILE 13
162 #define REGS_PER_LINE 8
163 #define LAST_VOLATILE 12
166 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
168 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
169 || ('a' <= (c) && (c) <= 'f') \
170 || ('A' <= (c) && (c) <= 'F'))
171 #define isalnum(c) (('0' <= (c) && (c) <= '9') \
172 || ('a' <= (c) && (c) <= 'z') \
173 || ('A' <= (c) && (c) <= 'Z'))
174 #define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
176 static char *help_string = "\
178 b show breakpoints\n\
179 bd set data breakpoint\n\
180 bi set instruction breakpoint\n\
181 bc clear breakpoint\n"
184 c print cpus stopped in xmon\n\
185 c# try to switch to cpu number h (in hex)\n"
190 di dump instructions\n\
191 df dump float values\n\
192 dd dump double values\n\
193 e print exception information\n\
195 la lookup symbol+offset of specified address\n\
196 ls lookup address of specified symbol\n\
197 m examine/change memory\n\
198 mm move a block of memory\n\
199 ms set a block of memory\n\
200 md compare two blocks of memory\n\
201 ml locate a block of memory\n\
202 mz zero a block of memory\n\
203 mi show information about memory allocation\n\
204 p call a procedure\n\
207 S print special registers\n\
209 x exit monitor and recover\n\
210 X exit monitor and dont recover\n"
212 " u dump segment table or SLB\n"
214 #ifdef CONFIG_PPC_STD_MMU_32
215 " u dump segment registers\n"
222 static struct pt_regs *xmon_regs;
224 static inline void sync(void)
226 asm volatile("sync; isync");
229 static inline void store_inst(void *p)
231 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
234 static inline void cflush(void *p)
236 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
239 static inline void cinval(void *p)
241 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
245 * Disable surveillance (the service processor watchdog function)
246 * while we are in xmon.
247 * XXX we should re-enable it when we leave. :)
249 #define SURVEILLANCE_TOKEN 9000
251 static inline void disable_surveillance(void)
253 #ifdef CONFIG_PPC_PSERIES
254 /* Since this can't be a module, args should end up below 4GB. */
255 static struct rtas_args args;
258 * At this point we have got all the cpus we can into
259 * xmon, so there is hopefully no other cpu calling RTAS
260 * at the moment, even though we don't take rtas.lock.
261 * If we did try to take rtas.lock there would be a
262 * real possibility of deadlock.
264 args.token = rtas_token("set-indicator");
265 if (args.token == RTAS_UNKNOWN_SERVICE)
269 args.rets = &args.args[3];
270 args.args[0] = SURVEILLANCE_TOKEN;
273 enter_rtas(__pa(&args));
274 #endif /* CONFIG_PPC_PSERIES */
278 static int xmon_speaker;
280 static void get_output_lock(void)
282 int me = smp_processor_id() + 0x100;
283 int last_speaker = 0, prev;
286 if (xmon_speaker == me)
289 if (xmon_speaker == 0) {
290 last_speaker = cmpxchg(&xmon_speaker, 0, me);
291 if (last_speaker == 0)
295 while (xmon_speaker == last_speaker) {
298 /* hostile takeover */
299 prev = cmpxchg(&xmon_speaker, last_speaker, me);
300 if (prev == last_speaker)
307 static void release_output_lock(void)
313 int xmon_core(struct pt_regs *regs, int fromipi)
318 long recurse_jmp[JMP_BUF_LEN];
319 unsigned long offset;
323 unsigned long timeout;
327 mtmsr(msr & ~MSR_EE); /* disable interrupts */
329 bp = in_breakpoint_table(regs->nip, &offset);
331 regs->nip = bp->address + offset;
332 atomic_dec(&bp->ref_count);
338 cpu = smp_processor_id();
339 if (cpu_isset(cpu, cpus_in_xmon)) {
342 printf("cpu 0x%x: Exception %lx %s in xmon, "
343 "returning to main loop\n",
344 cpu, regs->trap, getvecname(TRAP(regs)));
345 release_output_lock();
346 longjmp(xmon_fault_jmp[cpu], 1);
349 if (setjmp(recurse_jmp) != 0) {
350 if (!in_xmon || !xmon_gate) {
352 printf("xmon: WARNING: bad recursive fault "
353 "on cpu 0x%x\n", cpu);
354 release_output_lock();
357 secondary = !(xmon_taken && cpu == xmon_owner);
361 xmon_fault_jmp[cpu] = recurse_jmp;
362 cpu_set(cpu, cpus_in_xmon);
365 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
366 bp = at_breakpoint(regs->nip);
367 if (bp || (regs->msr & MSR_RI) == 0)
374 printf("cpu 0x%x stopped at breakpoint 0x%x (",
376 xmon_print_symbol(regs->nip, " ", ")\n");
378 if ((regs->msr & MSR_RI) == 0)
379 printf("WARNING: exception is not recoverable, "
381 release_output_lock();
386 while (secondary && !xmon_gate) {
390 secondary = test_and_set_bit(0, &in_xmon);
395 if (!secondary && !xmon_gate) {
396 /* we are the first cpu to come in */
397 /* interrupt other cpu(s) */
398 int ncpus = num_online_cpus();
403 smp_send_debugger_break(MSG_ALL_BUT_SELF);
404 /* wait for other cpus to come in */
405 for (timeout = 100000000; timeout != 0; --timeout) {
406 if (cpus_weight(cpus_in_xmon) >= ncpus)
412 disable_surveillance();
413 /* for breakpoint or single step, print the current instr. */
414 if (bp || TRAP(regs) == 0xd00)
415 ppc_inst_dump(regs->nip, 1, 0);
416 printf("enter ? for help\n");
425 if (cpu == xmon_owner) {
426 if (!test_and_set_bit(0, &xmon_taken)) {
431 while (cpu == xmon_owner)
445 /* have switched to some other cpu */
450 cpu_clear(cpu, cpus_in_xmon);
451 xmon_fault_jmp[cpu] = NULL;
454 /* UP is simple... */
456 printf("Exception %lx %s in xmon, returning to main loop\n",
457 regs->trap, getvecname(TRAP(regs)));
458 longjmp(xmon_fault_jmp[0], 1);
460 if (setjmp(recurse_jmp) == 0) {
461 xmon_fault_jmp[0] = recurse_jmp;
465 bp = at_breakpoint(regs->nip);
467 printf("Stopped at breakpoint %x (", BP_NUM(bp));
468 xmon_print_symbol(regs->nip, " ", ")\n");
470 if ((regs->msr & MSR_RI) == 0)
471 printf("WARNING: exception is not recoverable, "
474 disable_surveillance();
475 /* for breakpoint or single step, print the current instr. */
476 if (bp || TRAP(regs) == 0xd00)
477 ppc_inst_dump(regs->nip, 1, 0);
478 printf("enter ? for help\n");
487 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
488 bp = at_breakpoint(regs->nip);
490 int stepped = emulate_step(regs, bp->instr[0]);
492 regs->nip = (unsigned long) &bp->instr[0];
493 atomic_inc(&bp->ref_count);
494 } else if (stepped < 0) {
495 printf("Couldn't single-step %s instruction\n",
496 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
503 mtmsr(msr); /* restore interrupt enable */
508 int xmon(struct pt_regs *excp)
513 xmon_save_regs(®s);
516 return xmon_core(excp, 0);
521 xmon_irq(int irq, void *d, struct pt_regs *regs)
524 local_irq_save(flags);
525 printf("Keyboard interrupt\n");
527 local_irq_restore(flags);
531 int xmon_bpt(struct pt_regs *regs)
534 unsigned long offset;
536 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
539 /* Are we at the trap at bp->instr[1] for some bp? */
540 bp = in_breakpoint_table(regs->nip, &offset);
541 if (bp != NULL && offset == 4) {
542 regs->nip = bp->address + 4;
543 atomic_dec(&bp->ref_count);
547 /* Are we at a breakpoint? */
548 bp = at_breakpoint(regs->nip);
557 int xmon_sstep(struct pt_regs *regs)
565 int xmon_dabr_match(struct pt_regs *regs)
567 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
569 if (dabr.enabled == 0)
575 int xmon_iabr_match(struct pt_regs *regs)
577 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
585 int xmon_ipi(struct pt_regs *regs)
588 if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
594 int xmon_fault_handler(struct pt_regs *regs)
597 unsigned long offset;
599 if (in_xmon && catch_memory_errors)
600 handle_fault(regs); /* doesn't return */
602 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
603 bp = in_breakpoint_table(regs->nip, &offset);
605 regs->nip = bp->address + offset;
606 atomic_dec(&bp->ref_count);
613 static struct bpt *at_breakpoint(unsigned long pc)
619 for (i = 0; i < NBPTS; ++i, ++bp)
620 if (bp->enabled && pc == bp->address)
625 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
629 off = nip - (unsigned long) bpts;
630 if (off >= sizeof(bpts))
632 off %= sizeof(struct bpt);
633 if (off != offsetof(struct bpt, instr[0])
634 && off != offsetof(struct bpt, instr[1]))
636 *offp = off - offsetof(struct bpt, instr[0]);
637 return (struct bpt *) (nip - off);
640 static struct bpt *new_breakpoint(unsigned long a)
645 bp = at_breakpoint(a);
649 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
650 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
652 bp->instr[1] = bpinstr;
653 store_inst(&bp->instr[1]);
658 printf("Sorry, no free breakpoints. Please clear one first.\n");
662 static void insert_bpts(void)
668 for (i = 0; i < NBPTS; ++i, ++bp) {
669 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
671 if (mread(bp->address, &bp->instr[0], 4) != 4) {
672 printf("Couldn't read instruction at %lx, "
673 "disabling breakpoint there\n", bp->address);
677 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
678 printf("Breakpoint at %lx is on an mtmsrd or rfid "
679 "instruction, disabling it\n", bp->address);
683 store_inst(&bp->instr[0]);
684 if (bp->enabled & BP_IABR)
686 if (mwrite(bp->address, &bpinstr, 4) != 4) {
687 printf("Couldn't write instruction at %lx, "
688 "disabling breakpoint there\n", bp->address);
689 bp->enabled &= ~BP_TRAP;
692 store_inst((void *)bp->address);
696 static void insert_cpu_bpts(void)
699 set_dabr(dabr.address | (dabr.enabled & 7));
700 if (iabr && cpu_has_feature(CPU_FTR_IABR))
701 mtspr(SPRN_IABR, iabr->address
702 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
705 static void remove_bpts(void)
712 for (i = 0; i < NBPTS; ++i, ++bp) {
713 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
715 if (mread(bp->address, &instr, 4) == 4
717 && mwrite(bp->address, &bp->instr, 4) != 4)
718 printf("Couldn't remove breakpoint at %lx\n",
721 store_inst((void *)bp->address);
725 static void remove_cpu_bpts(void)
728 if (cpu_has_feature(CPU_FTR_IABR))
732 /* Command interpreting routine */
733 static char *last_cmd;
736 cmds(struct pt_regs *excp)
744 printf("%x:", smp_processor_id());
745 #endif /* CONFIG_SMP */
751 if (last_cmd == NULL)
753 take_input(last_cmd);
787 prregs(excp); /* print regs */
828 #ifdef CONFIG_PPC_STD_MMU
834 printf("Unrecognized command: ");
836 if (' ' < cmd && cmd <= '~')
839 printf("\\x%x", cmd);
841 } while (cmd != '\n');
842 printf(" (type ? for help)\n");
849 * Step a single instruction.
850 * Some instructions we emulate, others we execute with MSR_SE set.
852 static int do_step(struct pt_regs *regs)
857 /* check we are in 64-bit kernel mode, translation enabled */
858 if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
859 if (mread(regs->nip, &instr, 4) == 4) {
860 stepped = emulate_step(regs, instr);
862 printf("Couldn't single-step %s instruction\n",
863 (IS_RFID(instr)? "rfid": "mtmsrd"));
867 regs->trap = 0xd00 | (regs->trap & 1);
868 printf("stepped to ");
869 xmon_print_symbol(regs->nip, " ", "\n");
870 ppc_inst_dump(regs->nip, 1, 0);
879 static void bootcmds(void)
885 ppc_md.restart(NULL);
892 static int cpu_cmd(void)
899 if (!scanhex(&cpu)) {
900 /* print cpus waiting or in xmon */
901 printf("cpus stopped:");
903 for (cpu = 0; cpu < NR_CPUS; ++cpu) {
904 if (cpu_isset(cpu, cpus_in_xmon)) {
910 printf("-%x", cpu - 1);
915 printf("-%x", NR_CPUS - 1);
919 /* try to switch to cpu specified */
920 if (!cpu_isset(cpu, cpus_in_xmon)) {
921 printf("cpu 0x%x isn't in xmon\n", cpu);
928 while (!xmon_taken) {
929 if (--timeout == 0) {
930 if (test_and_set_bit(0, &xmon_taken))
932 /* take control back */
934 xmon_owner = smp_processor_id();
935 printf("cpu %u didn't take control\n", cpu);
943 #endif /* CONFIG_SMP */
946 static unsigned short fcstab[256] = {
947 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
948 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
949 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
950 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
951 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
952 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
953 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
954 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
955 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
956 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
957 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
958 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
959 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
960 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
961 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
962 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
963 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
964 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
965 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
966 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
967 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
968 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
969 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
970 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
971 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
972 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
973 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
974 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
975 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
976 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
977 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
978 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
981 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
992 if (!scanhex(&ncsum))
995 for (i = 0; i < ncsum; ++i) {
996 if (mread(adrs+i, &v, 1) == 0) {
997 printf("csum stopped at %x\n", adrs+i);
1002 printf("%x\n", fcs);
1006 * Check if this is a suitable place to put a breakpoint.
1008 static long check_bp_loc(unsigned long addr)
1013 if (addr < KERNELBASE) {
1014 printf("Breakpoints may only be placed at kernel addresses\n");
1017 if (!mread(addr, &instr, sizeof(instr))) {
1018 printf("Can't read instruction at address %lx\n", addr);
1021 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1022 printf("Breakpoints may not be placed on mtmsrd or rfid "
1029 static char *breakpoint_help_string =
1030 "Breakpoint command usage:\n"
1031 "b show breakpoints\n"
1032 "b <addr> [cnt] set breakpoint at given instr addr\n"
1033 "bc clear all breakpoints\n"
1034 "bc <n/addr> clear breakpoint number n or at addr\n"
1035 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1036 "bd <addr> [cnt] set hardware data breakpoint\n"
1046 const char badaddr[] = "Only kernel addresses are permitted "
1047 "for breakpoints\n";
1052 case 'd': /* bd - hardware data breakpoint */
1057 else if (cmd == 'w')
1063 if (scanhex(&dabr.address)) {
1064 if (dabr.address < KERNELBASE) {
1069 dabr.enabled = mode | BP_DABR;
1073 case 'i': /* bi - hardware instr breakpoint */
1074 if (!cpu_has_feature(CPU_FTR_IABR)) {
1075 printf("Hardware instruction breakpoint "
1076 "not supported on this cpu\n");
1080 iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1085 if (!check_bp_loc(a))
1087 bp = new_breakpoint(a);
1089 bp->enabled |= BP_IABR | BP_IABR_TE;
1097 /* clear all breakpoints */
1098 for (i = 0; i < NBPTS; ++i)
1099 bpts[i].enabled = 0;
1102 printf("All breakpoints cleared\n");
1106 if (a <= NBPTS && a >= 1) {
1107 /* assume a breakpoint number */
1108 bp = &bpts[a-1]; /* bp nums are 1 based */
1110 /* assume a breakpoint address */
1111 bp = at_breakpoint(a);
1113 printf("No breakpoint at %x\n", a);
1118 printf("Cleared breakpoint %x (", BP_NUM(bp));
1119 xmon_print_symbol(bp->address, " ", ")\n");
1127 printf(breakpoint_help_string);
1132 /* print all breakpoints */
1133 printf(" type address\n");
1135 printf(" data "REG" [", dabr.address);
1136 if (dabr.enabled & 1)
1138 if (dabr.enabled & 2)
1142 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1145 printf("%2x %s ", BP_NUM(bp),
1146 (bp->enabled & BP_IABR)? "inst": "trap");
1147 xmon_print_symbol(bp->address, " ", "\n");
1152 if (!check_bp_loc(a))
1154 bp = new_breakpoint(a);
1156 bp->enabled |= BP_TRAP;
1161 /* Very cheap human name for vector lookup. */
1163 const char *getvecname(unsigned long vec)
1168 case 0x100: ret = "(System Reset)"; break;
1169 case 0x200: ret = "(Machine Check)"; break;
1170 case 0x300: ret = "(Data Access)"; break;
1171 case 0x380: ret = "(Data SLB Access)"; break;
1172 case 0x400: ret = "(Instruction Access)"; break;
1173 case 0x480: ret = "(Instruction SLB Access)"; break;
1174 case 0x500: ret = "(Hardware Interrupt)"; break;
1175 case 0x600: ret = "(Alignment)"; break;
1176 case 0x700: ret = "(Program Check)"; break;
1177 case 0x800: ret = "(FPU Unavailable)"; break;
1178 case 0x900: ret = "(Decrementer)"; break;
1179 case 0xc00: ret = "(System Call)"; break;
1180 case 0xd00: ret = "(Single Step)"; break;
1181 case 0xf00: ret = "(Performance Monitor)"; break;
1182 case 0xf20: ret = "(Altivec Unavailable)"; break;
1183 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1189 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1190 unsigned long *endp)
1192 unsigned long size, offset;
1196 *startp = *endp = 0;
1199 if (setjmp(bus_error_jmp) == 0) {
1200 catch_memory_errors = 1;
1202 name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr);
1204 *startp = pc - offset;
1205 *endp = pc - offset + size;
1209 catch_memory_errors = 0;
1212 static int xmon_depth_to_print = 64;
1215 #define LRSAVE_OFFSET 0x10
1216 #define REG_FRAME_MARKER 0x7265677368657265ul /* "regshere" */
1217 #define MARKER_OFFSET 0x60
1218 #define REGS_OFFSET 0x70
1220 #define LRSAVE_OFFSET 4
1221 #define REG_FRAME_MARKER 0x72656773
1222 #define MARKER_OFFSET 8
1223 #define REGS_OFFSET 16
1226 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1230 unsigned long newsp;
1231 unsigned long marker;
1233 struct pt_regs regs;
1236 if (sp < PAGE_OFFSET) {
1238 printf("SP (%lx) is in userspace\n", sp);
1242 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1243 || !mread(sp, &newsp, sizeof(unsigned long))) {
1244 printf("Couldn't read stack frame at %lx\n", sp);
1249 * For the first stack frame, try to work out if
1250 * LR and/or the saved LR value in the bottommost
1251 * stack frame are valid.
1253 if ((pc | lr) != 0) {
1254 unsigned long fnstart, fnend;
1255 unsigned long nextip;
1258 get_function_bounds(pc, &fnstart, &fnend);
1261 mread(newsp + LRSAVE_OFFSET, &nextip,
1262 sizeof(unsigned long));
1264 if (lr < PAGE_OFFSET
1265 || (fnstart <= lr && lr < fnend))
1267 } else if (lr == nextip) {
1269 } else if (lr >= PAGE_OFFSET
1270 && !(fnstart <= lr && lr < fnend)) {
1271 printf("[link register ] ");
1272 xmon_print_symbol(lr, " ", "\n");
1275 printf("["REG"] ", sp);
1276 xmon_print_symbol(ip, " ", " (unreliable)\n");
1281 printf("["REG"] ", sp);
1282 xmon_print_symbol(ip, " ", "\n");
1285 /* Look for "regshere" marker to see if this is
1286 an exception frame. */
1287 if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1288 && marker == REG_FRAME_MARKER) {
1289 if (mread(sp + REGS_OFFSET, ®s, sizeof(regs))
1291 printf("Couldn't read registers at %lx\n",
1295 printf("--- Exception: %lx %s at ", regs.trap,
1296 getvecname(TRAP(®s)));
1299 xmon_print_symbol(pc, " ", "\n");
1306 } while (count++ < xmon_depth_to_print);
1309 static void backtrace(struct pt_regs *excp)
1314 xmon_show_stack(sp, 0, 0);
1316 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1320 static void print_bug_trap(struct pt_regs *regs)
1322 struct bug_entry *bug;
1325 if (regs->msr & MSR_PR)
1326 return; /* not in kernel */
1327 addr = regs->nip; /* address of trap instruction */
1328 if (addr < PAGE_OFFSET)
1330 bug = find_bug(regs->nip);
1333 if (bug->line & BUG_WARNING_TRAP)
1336 printf("kernel BUG in %s at %s:%d!\n",
1337 bug->function, bug->file, (unsigned int)bug->line);
1340 void excprint(struct pt_regs *fp)
1345 printf("cpu 0x%x: ", smp_processor_id());
1346 #endif /* CONFIG_SMP */
1349 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1351 xmon_print_symbol(fp->nip, ": ", "\n");
1353 printf(" lr: ", fp->link);
1354 xmon_print_symbol(fp->link, ": ", "\n");
1356 printf(" sp: %lx\n", fp->gpr[1]);
1357 printf(" msr: %lx\n", fp->msr);
1359 if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1360 printf(" dar: %lx\n", fp->dar);
1362 printf(" dsisr: %lx\n", fp->dsisr);
1365 printf(" current = 0x%lx\n", current);
1367 printf(" paca = 0x%lx\n", get_paca());
1370 printf(" pid = %ld, comm = %s\n",
1371 current->pid, current->comm);
1378 void prregs(struct pt_regs *fp)
1382 struct pt_regs regs;
1384 if (scanhex(&base)) {
1385 if (setjmp(bus_error_jmp) == 0) {
1386 catch_memory_errors = 1;
1388 regs = *(struct pt_regs *)base;
1392 catch_memory_errors = 0;
1393 printf("*** Error reading registers from "REG"\n",
1397 catch_memory_errors = 0;
1402 if (FULL_REGS(fp)) {
1403 for (n = 0; n < 16; ++n)
1404 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1405 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1407 for (n = 0; n < 7; ++n)
1408 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1409 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1412 for (n = 0; n < 32; ++n) {
1413 printf("R%.2d = %.8x%s", n, fp->gpr[n],
1414 (n & 3) == 3? "\n": " ");
1415 if (n == 12 && !FULL_REGS(fp)) {
1422 xmon_print_symbol(fp->nip, " ", "\n");
1424 xmon_print_symbol(fp->link, " ", "\n");
1425 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
1426 printf("ctr = "REG" xer = "REG" trap = %4lx\n",
1427 fp->ctr, fp->xer, fp->trap);
1429 if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1430 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1433 void cacheflush(void)
1436 unsigned long nflush;
1441 scanhex((void *)&adrs);
1446 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1447 if (setjmp(bus_error_jmp) == 0) {
1448 catch_memory_errors = 1;
1452 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1453 cflush((void *) adrs);
1455 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1456 cinval((void *) adrs);
1459 /* wait a little while to see if we get a machine check */
1462 catch_memory_errors = 0;
1468 unsigned int instrs[2];
1469 unsigned long (*code)(void);
1470 unsigned long opd[3];
1471 unsigned long ret = -1UL;
1473 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1474 instrs[1] = 0x4e800020;
1475 opd[0] = (unsigned long)instrs;
1479 store_inst(instrs+1);
1480 code = (unsigned long (*)(void)) opd;
1482 if (setjmp(bus_error_jmp) == 0) {
1483 catch_memory_errors = 1;
1489 /* wait a little while to see if we get a machine check */
1498 write_spr(int n, unsigned long val)
1500 unsigned int instrs[2];
1501 unsigned long (*code)(unsigned long);
1502 unsigned long opd[3];
1504 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1505 instrs[1] = 0x4e800020;
1506 opd[0] = (unsigned long)instrs;
1510 store_inst(instrs+1);
1511 code = (unsigned long (*)(unsigned long)) opd;
1513 if (setjmp(bus_error_jmp) == 0) {
1514 catch_memory_errors = 1;
1520 /* wait a little while to see if we get a machine check */
1526 static unsigned long regno;
1527 extern char exc_prolog;
1528 extern char dec_exc;
1530 void super_regs(void)
1534 #ifdef CONFIG_PPC_ISERIES
1535 struct paca_struct *ptrPaca = NULL;
1536 struct lppaca *ptrLpPaca = NULL;
1537 struct ItLpRegSave *ptrLpRegSave = NULL;
1542 unsigned long sp, toc;
1543 asm("mr %0,1" : "=r" (sp) :);
1544 asm("mr %0,2" : "=r" (toc) :);
1546 printf("msr = "REG" sprg0= "REG"\n",
1547 mfmsr(), mfspr(SPRN_SPRG0));
1548 printf("pvr = "REG" sprg1= "REG"\n",
1549 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
1550 printf("dec = "REG" sprg2= "REG"\n",
1551 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1552 printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1553 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
1554 #ifdef CONFIG_PPC_ISERIES
1555 // Dump out relevant Paca data areas.
1557 ptrPaca = get_paca();
1559 printf(" Local Processor Control Area (LpPaca): \n");
1560 ptrLpPaca = ptrPaca->lppaca_ptr;
1561 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1562 ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
1563 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1564 ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
1565 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
1567 printf(" Local Processor Register Save Area (LpRegSave): \n");
1568 ptrLpRegSave = ptrPaca->reg_save_ptr;
1569 printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n",
1570 ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
1571 printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n",
1572 ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
1573 printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n",
1574 ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
1583 val = read_spr(regno);
1585 write_spr(regno, val);
1588 printf("spr %lx = %lx\n", regno, read_spr(regno));
1595 * Stuff for reading and writing memory safely
1598 mread(unsigned long adrs, void *buf, int size)
1604 if (setjmp(bus_error_jmp) == 0) {
1605 catch_memory_errors = 1;
1611 *(u16 *)q = *(u16 *)p;
1614 *(u32 *)q = *(u32 *)p;
1617 *(u64 *)q = *(u64 *)p;
1620 for( ; n < size; ++n) {
1626 /* wait a little while to see if we get a machine check */
1630 catch_memory_errors = 0;
1635 mwrite(unsigned long adrs, void *buf, int size)
1641 if (setjmp(bus_error_jmp) == 0) {
1642 catch_memory_errors = 1;
1648 *(u16 *)p = *(u16 *)q;
1651 *(u32 *)p = *(u32 *)q;
1654 *(u64 *)p = *(u64 *)q;
1657 for ( ; n < size; ++n) {
1663 /* wait a little while to see if we get a machine check */
1667 printf("*** Error writing address %x\n", adrs + n);
1669 catch_memory_errors = 0;
1673 static int fault_type;
1674 static int fault_except;
1675 static char *fault_chars[] = { "--", "**", "##" };
1677 static int handle_fault(struct pt_regs *regs)
1679 fault_except = TRAP(regs);
1680 switch (TRAP(regs)) {
1692 longjmp(bus_error_jmp, 1);
1697 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1700 byterev(unsigned char *val, int size)
1706 SWAP(val[0], val[1], t);
1709 SWAP(val[0], val[3], t);
1710 SWAP(val[1], val[2], t);
1712 case 8: /* is there really any use for this? */
1713 SWAP(val[0], val[7], t);
1714 SWAP(val[1], val[6], t);
1715 SWAP(val[2], val[5], t);
1716 SWAP(val[3], val[4], t);
1724 static char *memex_help_string =
1725 "Memory examine command usage:\n"
1726 "m [addr] [flags] examine/change memory\n"
1727 " addr is optional. will start where left off.\n"
1728 " flags may include chars from this set:\n"
1729 " b modify by bytes (default)\n"
1730 " w modify by words (2 byte)\n"
1731 " l modify by longs (4 byte)\n"
1732 " d modify by doubleword (8 byte)\n"
1733 " r toggle reverse byte order mode\n"
1734 " n do not read memory (for i/o spaces)\n"
1735 " . ok to read (default)\n"
1736 "NOTE: flags are saved as defaults\n"
1739 static char *memex_subcmd_help_string =
1740 "Memory examine subcommands:\n"
1741 " hexval write this val to current location\n"
1742 " 'string' write chars from string to this location\n"
1743 " ' increment address\n"
1744 " ^ decrement address\n"
1745 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1746 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1747 " ` clear no-read flag\n"
1748 " ; stay at this addr\n"
1749 " v change to byte mode\n"
1750 " w change to word (2 byte) mode\n"
1751 " l change to long (4 byte) mode\n"
1752 " u change to doubleword (8 byte) mode\n"
1753 " m addr change current addr\n"
1754 " n toggle no-read flag\n"
1755 " r toggle byte reverse flag\n"
1756 " < count back up count bytes\n"
1757 " > count skip forward count bytes\n"
1758 " x exit this mode\n"
1764 int cmd, inc, i, nslash;
1766 unsigned char val[16];
1768 scanhex((void *)&adrs);
1771 printf(memex_help_string);
1777 while ((cmd = skipbl()) != '\n') {
1779 case 'b': size = 1; break;
1780 case 'w': size = 2; break;
1781 case 'l': size = 4; break;
1782 case 'd': size = 8; break;
1783 case 'r': brev = !brev; break;
1784 case 'n': mnoread = 1; break;
1785 case '.': mnoread = 0; break;
1794 n = mread(adrs, val, size);
1795 printf(REG"%c", adrs, brev? 'r': ' ');
1800 for (i = 0; i < n; ++i)
1801 printf("%.2x", val[i]);
1802 for (; i < size; ++i)
1803 printf("%s", fault_chars[fault_type]);
1810 for (i = 0; i < size; ++i)
1811 val[i] = n >> (i * 8);
1814 mwrite(adrs, val, size);
1827 else if( n == '\'' )
1829 for (i = 0; i < size; ++i)
1830 val[i] = n >> (i * 8);
1833 mwrite(adrs, val, size);
1870 adrs -= 1 << nslash;
1874 adrs += 1 << nslash;
1878 adrs += 1 << -nslash;
1882 adrs -= 1 << -nslash;
1885 scanhex((void *)&adrs);
1904 printf(memex_subcmd_help_string);
1919 case 'n': c = '\n'; break;
1920 case 'r': c = '\r'; break;
1921 case 'b': c = '\b'; break;
1922 case 't': c = '\t'; break;
1927 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
1928 || ('a' <= (c) && (c) <= 'f') \
1929 || ('A' <= (c) && (c) <= 'F'))
1936 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
1938 scanhex((void *)&adrs);
1945 else if (nidump > MAX_DUMP)
1947 adrs += ppc_inst_dump(adrs, nidump, 1);
1953 else if (ndump > MAX_DUMP)
1955 prdump(adrs, ndump);
1962 prdump(unsigned long adrs, long ndump)
1964 long n, m, c, r, nr;
1965 unsigned char temp[16];
1967 for (n = ndump; n > 0;) {
1971 nr = mread(adrs, temp, r);
1973 for (m = 0; m < r; ++m) {
1974 if ((m & (sizeof(long) - 1)) == 0 && m > 0)
1977 printf("%.2x", temp[m]);
1979 printf("%s", fault_chars[fault_type]);
1981 for (; m < 16; ++m) {
1982 if ((m & (sizeof(long) - 1)) == 0)
1987 for (m = 0; m < r; ++m) {
1990 putchar(' ' <= c && c <= '~'? c: '.');
2004 ppc_inst_dump(unsigned long adr, long count, int praddr)
2007 unsigned long first_adr;
2008 unsigned long inst, last_inst = 0;
2009 unsigned char val[4];
2012 for (first_adr = adr; count > 0; --count, adr += 4) {
2013 nr = mread(adr, val, 4);
2016 const char *x = fault_chars[fault_type];
2017 printf(REG" %s%s%s%s\n", adr, x, x, x, x);
2021 inst = GETWORD(val);
2022 if (adr > first_adr && inst == last_inst) {
2032 printf(REG" %.8x", adr, inst);
2034 print_insn_powerpc(inst, adr, 0); /* always returns 4 */
2037 return adr - first_adr;
2041 print_address(unsigned long addr)
2043 xmon_print_symbol(addr, "\t# ", "");
2048 * Memory operations - move, set, print differences
2050 static unsigned long mdest; /* destination address */
2051 static unsigned long msrc; /* source address */
2052 static unsigned long mval; /* byte value to set memory to */
2053 static unsigned long mcount; /* # bytes to affect */
2054 static unsigned long mdiffs; /* max # differences to print */
2059 scanhex((void *)&mdest);
2060 if( termch != '\n' )
2062 scanhex((void *)(cmd == 's'? &mval: &msrc));
2063 if( termch != '\n' )
2065 scanhex((void *)&mcount);
2068 memmove((void *)mdest, (void *)msrc, mcount);
2071 memset((void *)mdest, mval, mcount);
2074 if( termch != '\n' )
2076 scanhex((void *)&mdiffs);
2077 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2083 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2088 for( n = nb; n > 0; --n )
2089 if( *p1++ != *p2++ )
2090 if( ++prt <= maxpr )
2091 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2092 p1[-1], p2 - 1, p2[-1]);
2094 printf("Total of %d differences\n", prt);
2097 static unsigned mend;
2098 static unsigned mask;
2104 unsigned char val[4];
2107 scanhex((void *)&mdest);
2108 if (termch != '\n') {
2110 scanhex((void *)&mend);
2111 if (termch != '\n') {
2113 scanhex((void *)&mval);
2115 if (termch != '\n') termch = 0;
2116 scanhex((void *)&mask);
2120 for (a = mdest; a < mend; a += 4) {
2121 if (mread(a, val, 4) == 4
2122 && ((GETWORD(val) ^ mval) & mask) == 0) {
2123 printf("%.16x: %.16x\n", a, GETWORD(val));
2130 static unsigned long mskip = 0x1000;
2131 static unsigned long mlim = 0xffffffff;
2141 if (termch != '\n') termch = 0;
2143 if (termch != '\n') termch = 0;
2146 for (a = mdest; a < mlim; a += mskip) {
2147 ok = mread(a, &v, 1);
2149 printf("%.8x .. ", a);
2150 } else if (!ok && ook)
2151 printf("%.8x\n", a - mskip);
2157 printf("%.8x\n", a - mskip);
2162 unsigned long args[8];
2165 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2166 unsigned long, unsigned long, unsigned long,
2167 unsigned long, unsigned long, unsigned long);
2170 if (!scanhex(&adrs))
2174 for (i = 0; i < 8; ++i)
2176 for (i = 0; i < 8; ++i) {
2177 if (!scanhex(&args[i]) || termch == '\n')
2181 func = (callfunc_t) adrs;
2183 if (setjmp(bus_error_jmp) == 0) {
2184 catch_memory_errors = 1;
2186 ret = func(args[0], args[1], args[2], args[3],
2187 args[4], args[5], args[6], args[7]);
2189 printf("return value is %x\n", ret);
2191 printf("*** %x exception occurred\n", fault_except);
2193 catch_memory_errors = 0;
2196 /* Input scanning routines */
2207 while( c == ' ' || c == '\t' )
2213 static char *regnames[N_PTREGS] = {
2214 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2215 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2216 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2217 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2218 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2224 "trap", "dar", "dsisr", "res"
2228 scanhex(unsigned long *vp)
2235 /* parse register name */
2239 for (i = 0; i < sizeof(regname) - 1; ++i) {
2248 for (i = 0; i < N_PTREGS; ++i) {
2249 if (strcmp(regnames[i], regname) == 0) {
2250 if (xmon_regs == NULL) {
2251 printf("regs not available\n");
2254 *vp = ((unsigned long *)xmon_regs)[i];
2258 printf("invalid register name '%%%s'\n", regname);
2262 /* skip leading "0x" if any */
2276 } else if (c == '$') {
2278 for (i=0; i<63; i++) {
2288 if (setjmp(bus_error_jmp) == 0) {
2289 catch_memory_errors = 1;
2291 *vp = kallsyms_lookup_name(tmpstr);
2294 catch_memory_errors = 0;
2296 printf("unknown symbol '%s'\n", tmpstr);
2331 if( '0' <= c && c <= '9' )
2333 if( 'A' <= c && c <= 'F' )
2334 return c - ('A' - 10);
2335 if( 'a' <= c && c <= 'f' )
2336 return c - ('a' - 10);
2341 getstring(char *s, int size)
2352 } while( c != ' ' && c != '\t' && c != '\n' );
2357 static char line[256];
2358 static char *lineptr;
2369 if (lineptr == NULL || *lineptr == 0) {
2370 if (xmon_gets(line, sizeof(line)) == NULL) {
2380 take_input(char *str)
2389 int type = inchar();
2391 static char tmp[64];
2396 xmon_print_symbol(addr, ": ", "\n");
2401 if (setjmp(bus_error_jmp) == 0) {
2402 catch_memory_errors = 1;
2404 addr = kallsyms_lookup_name(tmp);
2406 printf("%s: %lx\n", tmp, addr);
2408 printf("Symbol '%s' not found.\n", tmp);
2411 catch_memory_errors = 0;
2418 /* Print an address in numeric and symbolic form (if possible) */
2419 static void xmon_print_symbol(unsigned long address, const char *mid,
2423 const char *name = NULL;
2424 unsigned long offset, size;
2426 printf(REG, address);
2427 if (setjmp(bus_error_jmp) == 0) {
2428 catch_memory_errors = 1;
2430 name = kallsyms_lookup(address, &size, &offset, &modname,
2433 /* wait a little while to see if we get a machine check */
2437 catch_memory_errors = 0;
2440 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2442 printf(" [%s]", modname);
2444 printf("%s", after);
2448 static void dump_slb(void)
2453 printf("SLB contents of cpu %x\n", smp_processor_id());
2455 for (i = 0; i < SLB_NUM_ENTRIES; i++) {
2456 asm volatile("slbmfee %0,%1" : "=r" (tmp) : "r" (i));
2457 printf("%02d %016lx ", i, tmp);
2459 asm volatile("slbmfev %0,%1" : "=r" (tmp) : "r" (i));
2460 printf("%016lx\n", tmp);
2464 static void dump_stab(void)
2467 unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2469 printf("Segment table contents of cpu %x\n", smp_processor_id());
2471 for (i = 0; i < PAGE_SIZE/16; i++) {
2478 printf("%03d %016lx ", i, a);
2479 printf("%016lx\n", b);
2484 void dump_segments(void)
2486 if (cpu_has_feature(CPU_FTR_SLB))
2493 #ifdef CONFIG_PPC_STD_MMU_32
2494 void dump_segments(void)
2499 for (i = 0; i < 16; ++i)
2500 printf(" %x", mfsrin(i));
2505 void xmon_init(int enable)
2509 __debugger_ipi = xmon_ipi;
2510 __debugger_bpt = xmon_bpt;
2511 __debugger_sstep = xmon_sstep;
2512 __debugger_iabr_match = xmon_iabr_match;
2513 __debugger_dabr_match = xmon_dabr_match;
2514 __debugger_fault_handler = xmon_fault_handler;
2517 __debugger_ipi = NULL;
2518 __debugger_bpt = NULL;
2519 __debugger_sstep = NULL;
2520 __debugger_iabr_match = NULL;
2521 __debugger_dabr_match = NULL;
2522 __debugger_fault_handler = NULL;
2527 #ifdef CONFIG_MAGIC_SYSRQ
2528 static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs,
2529 struct tty_struct *tty)
2531 /* ensure xmon is enabled */
2536 static struct sysrq_key_op sysrq_xmon_op =
2538 .handler = sysrq_handle_xmon,
2540 .action_msg = "Entering xmon",
2543 static int __init setup_xmon_sysrq(void)
2545 register_sysrq_key('x', &sysrq_xmon_op);
2548 __initcall(setup_xmon_sysrq);
2549 #endif /* CONFIG_MAGIC_SYSRQ */