2 * Routines providing a simple monitor for use on the PowerMac.
4 * Copyright (C) 1996 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>
22 #include <asm/ptrace.h>
23 #include <asm/string.h>
25 #include <asm/machdep.h>
27 #ifdef CONFIG_PMAC_BACKLIGHT
28 #include <asm/backlight.h>
30 #include <asm/processor.h>
31 #include <asm/pgtable.h>
33 #include <asm/mmu_context.h>
34 #include <asm/cputable.h>
36 #include <asm/sstep.h>
40 #include <asm/hvcall.h>
46 #define scanhex xmon_scanhex
47 #define skipbl xmon_skipbl
50 cpumask_t cpus_in_xmon = CPU_MASK_NONE;
51 static unsigned long xmon_taken = 1;
52 static int xmon_owner;
54 #endif /* CONFIG_SMP */
56 static unsigned long in_xmon = 0;
58 static unsigned long adrs;
60 #define MAX_DUMP (128 * 1024)
61 static unsigned long ndump = 64;
62 static unsigned long nidump = 16;
63 static unsigned long ncsum = 4096;
65 static char tmpstr[128];
67 #define JMP_BUF_LEN 23
68 static long bus_error_jmp[JMP_BUF_LEN];
69 static int catch_memory_errors;
70 static long *xmon_fault_jmp[NR_CPUS];
71 #define setjmp xmon_setjmp
72 #define longjmp xmon_longjmp
74 /* Breakpoint stuff */
76 unsigned long address;
77 unsigned int instr[2];
83 /* Bits in bpt.enabled */
84 #define BP_IABR_TE 1 /* IABR translation enabled */
90 static struct bpt bpts[NBPTS];
91 static struct bpt dabr;
92 static struct bpt *iabr;
93 static unsigned bpinstr = 0x7fe00008; /* trap */
95 #define BP_NUM(bp) ((bp) - bpts + 1)
98 static int cmds(struct pt_regs *);
99 static int mread(unsigned long, void *, int);
100 static int mwrite(unsigned long, void *, int);
101 static int handle_fault(struct pt_regs *);
102 static void byterev(unsigned char *, int);
103 static void memex(void);
104 static int bsesc(void);
105 static void dump(void);
106 static void prdump(unsigned long, long);
107 static int ppc_inst_dump(unsigned long, long, int);
108 void print_address(unsigned long);
109 static void backtrace(struct pt_regs *);
110 static void excprint(struct pt_regs *);
111 static void prregs(struct pt_regs *);
112 static void memops(int);
113 static void memlocate(void);
114 static void memzcan(void);
115 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
117 int scanhex(unsigned long *valp);
118 static void scannl(void);
119 static int hexdigit(int);
120 void getstring(char *, int);
121 static void flush_input(void);
122 static int inchar(void);
123 static void take_input(char *);
124 static unsigned long read_spr(int);
125 static void write_spr(int, unsigned long);
126 static void super_regs(void);
127 static void remove_bpts(void);
128 static void insert_bpts(void);
129 static void remove_cpu_bpts(void);
130 static void insert_cpu_bpts(void);
131 static struct bpt *at_breakpoint(unsigned long pc);
132 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
133 static int do_step(struct pt_regs *);
134 static void bpt_cmds(void);
135 static void cacheflush(void);
136 static int cpu_cmd(void);
137 static void csum(void);
138 static void bootcmds(void);
139 static void proccall(void);
140 void dump_segments(void);
141 static void symbol_lookup(void);
142 static void xmon_print_symbol(unsigned long address, const char *mid,
144 static const char *getvecname(unsigned long vec);
146 extern int print_insn_powerpc(unsigned long, unsigned long, int);
147 extern void printf(const char *fmt, ...);
148 extern void xmon_vfprintf(void *f, const char *fmt, va_list ap);
149 extern int xmon_putc(int c, void *f);
150 extern int putchar(int ch);
152 extern void xmon_enter(void);
153 extern void xmon_leave(void);
155 extern int xmon_read_poll(void);
156 extern long setjmp(long *);
157 extern void longjmp(long *, long);
158 extern void xmon_save_regs(struct pt_regs *);
162 #define REGS_PER_LINE 4
163 #define LAST_VOLATILE 13
166 #define REGS_PER_LINE 8
167 #define LAST_VOLATILE 12
170 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
172 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
173 || ('a' <= (c) && (c) <= 'f') \
174 || ('A' <= (c) && (c) <= 'F'))
175 #define isalnum(c) (('0' <= (c) && (c) <= '9') \
176 || ('a' <= (c) && (c) <= 'z') \
177 || ('A' <= (c) && (c) <= 'Z'))
178 #define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
180 static char *help_string = "\
182 b show breakpoints\n\
183 bd set data breakpoint\n\
184 bi set instruction breakpoint\n\
185 bc clear breakpoint\n"
188 c print cpus stopped in xmon\n\
189 c# try to switch to cpu number h (in hex)\n"
194 di dump instructions\n\
195 df dump float values\n\
196 dd dump double values\n\
197 e print exception information\n\
199 la lookup symbol+offset of specified address\n\
200 ls lookup address of specified symbol\n\
201 m examine/change memory\n\
202 mm move a block of memory\n\
203 ms set a block of memory\n\
204 md compare two blocks of memory\n\
205 ml locate a block of memory\n\
206 mz zero a block of memory\n\
207 mi show information about memory allocation\n\
208 p call a procedure\n\
211 S print special registers\n\
213 T Enable/Disable PPCDBG flags\n\
214 x exit monitor and recover\n\
215 X exit monitor and dont recover\n"
217 " u dump segment table or SLB\n"
219 #ifdef CONFIG_PPC_STD_MMU_32
220 " u dump segment registers\n"
227 static struct pt_regs *xmon_regs;
229 static inline void sync(void)
231 asm volatile("sync; isync");
234 static inline void store_inst(void *p)
236 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
239 static inline void cflush(void *p)
241 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
244 static inline void cinval(void *p)
246 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
250 * Disable surveillance (the service processor watchdog function)
251 * while we are in xmon.
252 * XXX we should re-enable it when we leave. :)
254 #define SURVEILLANCE_TOKEN 9000
256 static inline void disable_surveillance(void)
258 #ifdef CONFIG_PPC_PSERIES
259 /* Since this can't be a module, args should end up below 4GB. */
260 static struct rtas_args args;
263 * At this point we have got all the cpus we can into
264 * xmon, so there is hopefully no other cpu calling RTAS
265 * at the moment, even though we don't take rtas.lock.
266 * If we did try to take rtas.lock there would be a
267 * real possibility of deadlock.
269 args.token = rtas_token("set-indicator");
270 if (args.token == RTAS_UNKNOWN_SERVICE)
274 args.rets = &args.args[3];
275 args.args[0] = SURVEILLANCE_TOKEN;
278 enter_rtas(__pa(&args));
279 #endif /* CONFIG_PPC_PSERIES */
283 static int xmon_speaker;
285 static void get_output_lock(void)
287 int me = smp_processor_id() + 0x100;
288 int last_speaker = 0, prev;
291 if (xmon_speaker == me)
294 if (xmon_speaker == 0) {
295 last_speaker = cmpxchg(&xmon_speaker, 0, me);
296 if (last_speaker == 0)
300 while (xmon_speaker == last_speaker) {
303 /* hostile takeover */
304 prev = cmpxchg(&xmon_speaker, last_speaker, me);
305 if (prev == last_speaker)
312 static void release_output_lock(void)
318 int xmon_core(struct pt_regs *regs, int fromipi)
323 long recurse_jmp[JMP_BUF_LEN];
324 unsigned long offset;
328 unsigned long timeout;
332 mtmsr(msr & ~MSR_EE); /* disable interrupts */
334 bp = in_breakpoint_table(regs->nip, &offset);
336 regs->nip = bp->address + offset;
337 atomic_dec(&bp->ref_count);
343 cpu = smp_processor_id();
344 if (cpu_isset(cpu, cpus_in_xmon)) {
347 printf("cpu 0x%x: Exception %lx %s in xmon, "
348 "returning to main loop\n",
349 cpu, regs->trap, getvecname(TRAP(regs)));
350 release_output_lock();
351 longjmp(xmon_fault_jmp[cpu], 1);
354 if (setjmp(recurse_jmp) != 0) {
355 if (!in_xmon || !xmon_gate) {
357 printf("xmon: WARNING: bad recursive fault "
358 "on cpu 0x%x\n", cpu);
359 release_output_lock();
362 secondary = !(xmon_taken && cpu == xmon_owner);
366 xmon_fault_jmp[cpu] = recurse_jmp;
367 cpu_set(cpu, cpus_in_xmon);
370 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
371 bp = at_breakpoint(regs->nip);
372 if (bp || (regs->msr & MSR_RI) == 0)
379 printf("cpu 0x%x stopped at breakpoint 0x%x (",
381 xmon_print_symbol(regs->nip, " ", ")\n");
383 if ((regs->msr & MSR_RI) == 0)
384 printf("WARNING: exception is not recoverable, "
386 release_output_lock();
391 while (secondary && !xmon_gate) {
395 secondary = test_and_set_bit(0, &in_xmon);
400 if (!secondary && !xmon_gate) {
401 /* we are the first cpu to come in */
402 /* interrupt other cpu(s) */
403 int ncpus = num_online_cpus();
408 smp_send_debugger_break(MSG_ALL_BUT_SELF);
409 /* wait for other cpus to come in */
410 for (timeout = 100000000; timeout != 0; --timeout) {
411 if (cpus_weight(cpus_in_xmon) >= ncpus)
417 disable_surveillance();
418 /* for breakpoint or single step, print the current instr. */
419 if (bp || TRAP(regs) == 0xd00)
420 ppc_inst_dump(regs->nip, 1, 0);
421 printf("enter ? for help\n");
430 if (cpu == xmon_owner) {
431 if (!test_and_set_bit(0, &xmon_taken)) {
436 while (cpu == xmon_owner)
450 /* have switched to some other cpu */
455 cpu_clear(cpu, cpus_in_xmon);
456 xmon_fault_jmp[cpu] = NULL;
459 /* UP is simple... */
461 printf("Exception %lx %s in xmon, returning to main loop\n",
462 regs->trap, getvecname(TRAP(regs)));
463 longjmp(xmon_fault_jmp[0], 1);
465 if (setjmp(recurse_jmp) == 0) {
466 xmon_fault_jmp[0] = recurse_jmp;
470 bp = at_breakpoint(regs->nip);
472 printf("Stopped at breakpoint %x (", BP_NUM(bp));
473 xmon_print_symbol(regs->nip, " ", ")\n");
475 if ((regs->msr & MSR_RI) == 0)
476 printf("WARNING: exception is not recoverable, "
479 disable_surveillance();
480 /* for breakpoint or single step, print the current instr. */
481 if (bp || TRAP(regs) == 0xd00)
482 ppc_inst_dump(regs->nip, 1, 0);
483 printf("enter ? for help\n");
492 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
493 bp = at_breakpoint(regs->nip);
495 int stepped = emulate_step(regs, bp->instr[0]);
497 regs->nip = (unsigned long) &bp->instr[0];
498 atomic_inc(&bp->ref_count);
499 } else if (stepped < 0) {
500 printf("Couldn't single-step %s instruction\n",
501 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
508 mtmsr(msr); /* restore interrupt enable */
513 int xmon(struct pt_regs *excp)
518 xmon_save_regs(®s);
521 return xmon_core(excp, 0);
526 xmon_irq(int irq, void *d, struct pt_regs *regs)
529 local_irq_save(flags);
530 printf("Keyboard interrupt\n");
532 local_irq_restore(flags);
536 int xmon_bpt(struct pt_regs *regs)
539 unsigned long offset;
541 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
544 /* Are we at the trap at bp->instr[1] for some bp? */
545 bp = in_breakpoint_table(regs->nip, &offset);
546 if (bp != NULL && offset == 4) {
547 regs->nip = bp->address + 4;
548 atomic_dec(&bp->ref_count);
552 /* Are we at a breakpoint? */
553 bp = at_breakpoint(regs->nip);
562 int xmon_sstep(struct pt_regs *regs)
570 int xmon_dabr_match(struct pt_regs *regs)
572 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
574 if (dabr.enabled == 0)
580 int xmon_iabr_match(struct pt_regs *regs)
582 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
590 int xmon_ipi(struct pt_regs *regs)
593 if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
599 int xmon_fault_handler(struct pt_regs *regs)
602 unsigned long offset;
604 if (in_xmon && catch_memory_errors)
605 handle_fault(regs); /* doesn't return */
607 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
608 bp = in_breakpoint_table(regs->nip, &offset);
610 regs->nip = bp->address + offset;
611 atomic_dec(&bp->ref_count);
618 static struct bpt *at_breakpoint(unsigned long pc)
624 for (i = 0; i < NBPTS; ++i, ++bp)
625 if (bp->enabled && pc == bp->address)
630 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
634 off = nip - (unsigned long) bpts;
635 if (off >= sizeof(bpts))
637 off %= sizeof(struct bpt);
638 if (off != offsetof(struct bpt, instr[0])
639 && off != offsetof(struct bpt, instr[1]))
641 *offp = off - offsetof(struct bpt, instr[0]);
642 return (struct bpt *) (nip - off);
645 static struct bpt *new_breakpoint(unsigned long a)
650 bp = at_breakpoint(a);
654 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
655 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
657 bp->instr[1] = bpinstr;
658 store_inst(&bp->instr[1]);
663 printf("Sorry, no free breakpoints. Please clear one first.\n");
667 static void insert_bpts(void)
673 for (i = 0; i < NBPTS; ++i, ++bp) {
674 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
676 if (mread(bp->address, &bp->instr[0], 4) != 4) {
677 printf("Couldn't read instruction at %lx, "
678 "disabling breakpoint there\n", bp->address);
682 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
683 printf("Breakpoint at %lx is on an mtmsrd or rfid "
684 "instruction, disabling it\n", bp->address);
688 store_inst(&bp->instr[0]);
689 if (bp->enabled & BP_IABR)
691 if (mwrite(bp->address, &bpinstr, 4) != 4) {
692 printf("Couldn't write instruction at %lx, "
693 "disabling breakpoint there\n", bp->address);
694 bp->enabled &= ~BP_TRAP;
697 store_inst((void *)bp->address);
701 static void insert_cpu_bpts(void)
704 set_dabr(dabr.address | (dabr.enabled & 7));
705 if (iabr && cpu_has_feature(CPU_FTR_IABR))
706 mtspr(SPRN_IABR, iabr->address
707 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
710 static void remove_bpts(void)
717 for (i = 0; i < NBPTS; ++i, ++bp) {
718 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
720 if (mread(bp->address, &instr, 4) == 4
722 && mwrite(bp->address, &bp->instr, 4) != 4)
723 printf("Couldn't remove breakpoint at %lx\n",
726 store_inst((void *)bp->address);
730 static void remove_cpu_bpts(void)
733 if (cpu_has_feature(CPU_FTR_IABR))
737 /* Command interpreting routine */
738 static char *last_cmd;
741 cmds(struct pt_regs *excp)
749 printf("%x:", smp_processor_id());
750 #endif /* CONFIG_SMP */
757 if (last_cmd == NULL)
759 take_input(last_cmd);
793 prregs(excp); /* print regs */
834 #ifdef CONFIG_PPC_STD_MMU
840 printf("Unrecognized command: ");
842 if (' ' < cmd && cmd <= '~')
845 printf("\\x%x", cmd);
847 } while (cmd != '\n');
848 printf(" (type ? for help)\n");
855 * Step a single instruction.
856 * Some instructions we emulate, others we execute with MSR_SE set.
858 static int do_step(struct pt_regs *regs)
863 /* check we are in 64-bit kernel mode, translation enabled */
864 if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
865 if (mread(regs->nip, &instr, 4) == 4) {
866 stepped = emulate_step(regs, instr);
868 printf("Couldn't single-step %s instruction\n",
869 (IS_RFID(instr)? "rfid": "mtmsrd"));
873 regs->trap = 0xd00 | (regs->trap & 1);
874 printf("stepped to ");
875 xmon_print_symbol(regs->nip, " ", "\n");
876 ppc_inst_dump(regs->nip, 1, 0);
885 static void bootcmds(void)
891 ppc_md.restart(NULL);
898 static int cpu_cmd(void)
905 if (!scanhex(&cpu)) {
906 /* print cpus waiting or in xmon */
907 printf("cpus stopped:");
909 for (cpu = 0; cpu < NR_CPUS; ++cpu) {
910 if (cpu_isset(cpu, cpus_in_xmon)) {
916 printf("-%x", cpu - 1);
921 printf("-%x", NR_CPUS - 1);
925 /* try to switch to cpu specified */
926 if (!cpu_isset(cpu, cpus_in_xmon)) {
927 printf("cpu 0x%x isn't in xmon\n", cpu);
934 while (!xmon_taken) {
935 if (--timeout == 0) {
936 if (test_and_set_bit(0, &xmon_taken))
938 /* take control back */
940 xmon_owner = smp_processor_id();
941 printf("cpu %u didn't take control\n", cpu);
949 #endif /* CONFIG_SMP */
952 static unsigned short fcstab[256] = {
953 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
954 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
955 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
956 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
957 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
958 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
959 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
960 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
961 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
962 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
963 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
964 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
965 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
966 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
967 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
968 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
969 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
970 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
971 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
972 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
973 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
974 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
975 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
976 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
977 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
978 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
979 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
980 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
981 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
982 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
983 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
984 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
987 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
998 if (!scanhex(&ncsum))
1001 for (i = 0; i < ncsum; ++i) {
1002 if (mread(adrs+i, &v, 1) == 0) {
1003 printf("csum stopped at %x\n", adrs+i);
1008 printf("%x\n", fcs);
1012 * Check if this is a suitable place to put a breakpoint.
1014 static long check_bp_loc(unsigned long addr)
1019 if (addr < KERNELBASE) {
1020 printf("Breakpoints may only be placed at kernel addresses\n");
1023 if (!mread(addr, &instr, sizeof(instr))) {
1024 printf("Can't read instruction at address %lx\n", addr);
1027 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1028 printf("Breakpoints may not be placed on mtmsrd or rfid "
1035 static char *breakpoint_help_string =
1036 "Breakpoint command usage:\n"
1037 "b show breakpoints\n"
1038 "b <addr> [cnt] set breakpoint at given instr addr\n"
1039 "bc clear all breakpoints\n"
1040 "bc <n/addr> clear breakpoint number n or at addr\n"
1041 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1042 "bd <addr> [cnt] set hardware data breakpoint\n"
1052 const char badaddr[] = "Only kernel addresses are permitted "
1053 "for breakpoints\n";
1058 case 'd': /* bd - hardware data breakpoint */
1063 else if (cmd == 'w')
1069 if (scanhex(&dabr.address)) {
1070 if (dabr.address < KERNELBASE) {
1075 dabr.enabled = mode | BP_DABR;
1079 case 'i': /* bi - hardware instr breakpoint */
1080 if (!cpu_has_feature(CPU_FTR_IABR)) {
1081 printf("Hardware instruction breakpoint "
1082 "not supported on this cpu\n");
1086 iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1091 if (!check_bp_loc(a))
1093 bp = new_breakpoint(a);
1095 bp->enabled |= BP_IABR | BP_IABR_TE;
1103 /* clear all breakpoints */
1104 for (i = 0; i < NBPTS; ++i)
1105 bpts[i].enabled = 0;
1108 printf("All breakpoints cleared\n");
1112 if (a <= NBPTS && a >= 1) {
1113 /* assume a breakpoint number */
1114 bp = &bpts[a-1]; /* bp nums are 1 based */
1116 /* assume a breakpoint address */
1117 bp = at_breakpoint(a);
1119 printf("No breakpoint at %x\n", a);
1124 printf("Cleared breakpoint %x (", BP_NUM(bp));
1125 xmon_print_symbol(bp->address, " ", ")\n");
1133 printf(breakpoint_help_string);
1138 /* print all breakpoints */
1139 printf(" type address\n");
1141 printf(" data "REG" [", dabr.address);
1142 if (dabr.enabled & 1)
1144 if (dabr.enabled & 2)
1148 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1151 printf("%2x %s ", BP_NUM(bp),
1152 (bp->enabled & BP_IABR)? "inst": "trap");
1153 xmon_print_symbol(bp->address, " ", "\n");
1158 if (!check_bp_loc(a))
1160 bp = new_breakpoint(a);
1162 bp->enabled |= BP_TRAP;
1167 /* Very cheap human name for vector lookup. */
1169 const char *getvecname(unsigned long vec)
1174 case 0x100: ret = "(System Reset)"; break;
1175 case 0x200: ret = "(Machine Check)"; break;
1176 case 0x300: ret = "(Data Access)"; break;
1177 case 0x380: ret = "(Data SLB Access)"; break;
1178 case 0x400: ret = "(Instruction Access)"; break;
1179 case 0x480: ret = "(Instruction SLB Access)"; break;
1180 case 0x500: ret = "(Hardware Interrupt)"; break;
1181 case 0x600: ret = "(Alignment)"; break;
1182 case 0x700: ret = "(Program Check)"; break;
1183 case 0x800: ret = "(FPU Unavailable)"; break;
1184 case 0x900: ret = "(Decrementer)"; break;
1185 case 0xc00: ret = "(System Call)"; break;
1186 case 0xd00: ret = "(Single Step)"; break;
1187 case 0xf00: ret = "(Performance Monitor)"; break;
1188 case 0xf20: ret = "(Altivec Unavailable)"; break;
1189 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1195 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1196 unsigned long *endp)
1198 unsigned long size, offset;
1202 *startp = *endp = 0;
1205 if (setjmp(bus_error_jmp) == 0) {
1206 catch_memory_errors = 1;
1208 name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr);
1210 *startp = pc - offset;
1211 *endp = pc - offset + size;
1215 catch_memory_errors = 0;
1218 static int xmon_depth_to_print = 64;
1221 #define LRSAVE_OFFSET 0x10
1222 #define REG_FRAME_MARKER 0x7265677368657265ul /* "regshere" */
1223 #define MARKER_OFFSET 0x60
1224 #define REGS_OFFSET 0x70
1226 #define LRSAVE_OFFSET 4
1227 #define REG_FRAME_MARKER 0x72656773
1228 #define MARKER_OFFSET 8
1229 #define REGS_OFFSET 16
1232 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1236 unsigned long newsp;
1237 unsigned long marker;
1239 struct pt_regs regs;
1242 if (sp < PAGE_OFFSET) {
1244 printf("SP (%lx) is in userspace\n", sp);
1248 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1249 || !mread(sp, &newsp, sizeof(unsigned long))) {
1250 printf("Couldn't read stack frame at %lx\n", sp);
1255 * For the first stack frame, try to work out if
1256 * LR and/or the saved LR value in the bottommost
1257 * stack frame are valid.
1259 if ((pc | lr) != 0) {
1260 unsigned long fnstart, fnend;
1261 unsigned long nextip;
1264 get_function_bounds(pc, &fnstart, &fnend);
1267 mread(newsp + LRSAVE_OFFSET, &nextip,
1268 sizeof(unsigned long));
1270 if (lr < PAGE_OFFSET
1271 || (fnstart <= lr && lr < fnend))
1273 } else if (lr == nextip) {
1275 } else if (lr >= PAGE_OFFSET
1276 && !(fnstart <= lr && lr < fnend)) {
1277 printf("[link register ] ");
1278 xmon_print_symbol(lr, " ", "\n");
1281 printf("["REG"] ", sp);
1282 xmon_print_symbol(ip, " ", " (unreliable)\n");
1287 printf("["REG"] ", sp);
1288 xmon_print_symbol(ip, " ", "\n");
1291 /* Look for "regshere" marker to see if this is
1292 an exception frame. */
1293 if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1294 && marker == REG_FRAME_MARKER) {
1295 if (mread(sp + REGS_OFFSET, ®s, sizeof(regs))
1297 printf("Couldn't read registers at %lx\n",
1301 printf("--- Exception: %lx %s at ", regs.trap,
1302 getvecname(TRAP(®s)));
1305 xmon_print_symbol(pc, " ", "\n");
1312 } while (count++ < xmon_depth_to_print);
1315 static void backtrace(struct pt_regs *excp)
1320 xmon_show_stack(sp, 0, 0);
1322 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1326 static void print_bug_trap(struct pt_regs *regs)
1328 struct bug_entry *bug;
1331 if (regs->msr & MSR_PR)
1332 return; /* not in kernel */
1333 addr = regs->nip; /* address of trap instruction */
1334 if (addr < PAGE_OFFSET)
1336 bug = find_bug(regs->nip);
1339 if (bug->line & BUG_WARNING_TRAP)
1342 printf("kernel BUG in %s at %s:%d!\n",
1343 bug->function, bug->file, (unsigned int)bug->line);
1346 void excprint(struct pt_regs *fp)
1351 printf("cpu 0x%x: ", smp_processor_id());
1352 #endif /* CONFIG_SMP */
1355 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1357 xmon_print_symbol(fp->nip, ": ", "\n");
1359 printf(" lr: ", fp->link);
1360 xmon_print_symbol(fp->link, ": ", "\n");
1362 printf(" sp: %lx\n", fp->gpr[1]);
1363 printf(" msr: %lx\n", fp->msr);
1365 if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1366 printf(" dar: %lx\n", fp->dar);
1368 printf(" dsisr: %lx\n", fp->dsisr);
1371 printf(" current = 0x%lx\n", current);
1373 printf(" paca = 0x%lx\n", get_paca());
1376 printf(" pid = %ld, comm = %s\n",
1377 current->pid, current->comm);
1384 void prregs(struct pt_regs *fp)
1388 struct pt_regs regs;
1390 if (scanhex(&base)) {
1391 if (setjmp(bus_error_jmp) == 0) {
1392 catch_memory_errors = 1;
1394 regs = *(struct pt_regs *)base;
1398 catch_memory_errors = 0;
1399 printf("*** Error reading registers from "REG"\n",
1403 catch_memory_errors = 0;
1408 if (FULL_REGS(fp)) {
1409 for (n = 0; n < 16; ++n)
1410 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1411 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1413 for (n = 0; n < 7; ++n)
1414 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1415 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1418 for (n = 0; n < 32; ++n) {
1419 printf("R%.2d = %.8x%s", n, fp->gpr[n],
1420 (n & 3) == 3? "\n": " ");
1421 if (n == 12 && !FULL_REGS(fp)) {
1428 xmon_print_symbol(fp->nip, " ", "\n");
1430 xmon_print_symbol(fp->link, " ", "\n");
1431 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
1432 printf("ctr = "REG" xer = "REG" trap = %4lx\n",
1433 fp->ctr, fp->xer, fp->trap);
1435 if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1436 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1439 void cacheflush(void)
1442 unsigned long nflush;
1447 scanhex((void *)&adrs);
1452 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1453 if (setjmp(bus_error_jmp) == 0) {
1454 catch_memory_errors = 1;
1458 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1459 cflush((void *) adrs);
1461 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1462 cinval((void *) adrs);
1465 /* wait a little while to see if we get a machine check */
1468 catch_memory_errors = 0;
1474 unsigned int instrs[2];
1475 unsigned long (*code)(void);
1476 unsigned long opd[3];
1477 unsigned long ret = -1UL;
1479 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1480 instrs[1] = 0x4e800020;
1481 opd[0] = (unsigned long)instrs;
1485 store_inst(instrs+1);
1486 code = (unsigned long (*)(void)) opd;
1488 if (setjmp(bus_error_jmp) == 0) {
1489 catch_memory_errors = 1;
1495 /* wait a little while to see if we get a machine check */
1504 write_spr(int n, unsigned long val)
1506 unsigned int instrs[2];
1507 unsigned long (*code)(unsigned long);
1508 unsigned long opd[3];
1510 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1511 instrs[1] = 0x4e800020;
1512 opd[0] = (unsigned long)instrs;
1516 store_inst(instrs+1);
1517 code = (unsigned long (*)(unsigned long)) opd;
1519 if (setjmp(bus_error_jmp) == 0) {
1520 catch_memory_errors = 1;
1526 /* wait a little while to see if we get a machine check */
1532 static unsigned long regno;
1533 extern char exc_prolog;
1534 extern char dec_exc;
1536 void super_regs(void)
1540 #ifdef CONFIG_PPC_ISERIES
1541 struct paca_struct *ptrPaca = NULL;
1542 struct lppaca *ptrLpPaca = NULL;
1543 struct ItLpRegSave *ptrLpRegSave = NULL;
1548 unsigned long sp, toc;
1549 asm("mr %0,1" : "=r" (sp) :);
1550 asm("mr %0,2" : "=r" (toc) :);
1552 printf("msr = "REG" sprg0= "REG"\n",
1553 mfmsr(), mfspr(SPRN_SPRG0));
1554 printf("pvr = "REG" sprg1= "REG"\n",
1555 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
1556 printf("dec = "REG" sprg2= "REG"\n",
1557 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1558 printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1559 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
1560 #ifdef CONFIG_PPC_ISERIES
1561 // Dump out relevant Paca data areas.
1563 ptrPaca = get_paca();
1565 printf(" Local Processor Control Area (LpPaca): \n");
1566 ptrLpPaca = ptrPaca->lppaca_ptr;
1567 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1568 ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
1569 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1570 ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
1571 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
1573 printf(" Local Processor Register Save Area (LpRegSave): \n");
1574 ptrLpRegSave = ptrPaca->reg_save_ptr;
1575 printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n",
1576 ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
1577 printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n",
1578 ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
1579 printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n",
1580 ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
1589 val = read_spr(regno);
1591 write_spr(regno, val);
1594 printf("spr %lx = %lx\n", regno, read_spr(regno));
1601 * Stuff for reading and writing memory safely
1604 mread(unsigned long adrs, void *buf, int size)
1610 if (setjmp(bus_error_jmp) == 0) {
1611 catch_memory_errors = 1;
1617 *(u16 *)q = *(u16 *)p;
1620 *(u32 *)q = *(u32 *)p;
1623 *(u64 *)q = *(u64 *)p;
1626 for( ; n < size; ++n) {
1632 /* wait a little while to see if we get a machine check */
1636 catch_memory_errors = 0;
1641 mwrite(unsigned long adrs, void *buf, int size)
1647 if (setjmp(bus_error_jmp) == 0) {
1648 catch_memory_errors = 1;
1654 *(u16 *)p = *(u16 *)q;
1657 *(u32 *)p = *(u32 *)q;
1660 *(u64 *)p = *(u64 *)q;
1663 for ( ; n < size; ++n) {
1669 /* wait a little while to see if we get a machine check */
1673 printf("*** Error writing address %x\n", adrs + n);
1675 catch_memory_errors = 0;
1679 static int fault_type;
1680 static int fault_except;
1681 static char *fault_chars[] = { "--", "**", "##" };
1683 static int handle_fault(struct pt_regs *regs)
1685 fault_except = TRAP(regs);
1686 switch (TRAP(regs)) {
1698 longjmp(bus_error_jmp, 1);
1703 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1706 byterev(unsigned char *val, int size)
1712 SWAP(val[0], val[1], t);
1715 SWAP(val[0], val[3], t);
1716 SWAP(val[1], val[2], t);
1718 case 8: /* is there really any use for this? */
1719 SWAP(val[0], val[7], t);
1720 SWAP(val[1], val[6], t);
1721 SWAP(val[2], val[5], t);
1722 SWAP(val[3], val[4], t);
1730 static char *memex_help_string =
1731 "Memory examine command usage:\n"
1732 "m [addr] [flags] examine/change memory\n"
1733 " addr is optional. will start where left off.\n"
1734 " flags may include chars from this set:\n"
1735 " b modify by bytes (default)\n"
1736 " w modify by words (2 byte)\n"
1737 " l modify by longs (4 byte)\n"
1738 " d modify by doubleword (8 byte)\n"
1739 " r toggle reverse byte order mode\n"
1740 " n do not read memory (for i/o spaces)\n"
1741 " . ok to read (default)\n"
1742 "NOTE: flags are saved as defaults\n"
1745 static char *memex_subcmd_help_string =
1746 "Memory examine subcommands:\n"
1747 " hexval write this val to current location\n"
1748 " 'string' write chars from string to this location\n"
1749 " ' increment address\n"
1750 " ^ decrement address\n"
1751 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1752 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1753 " ` clear no-read flag\n"
1754 " ; stay at this addr\n"
1755 " v change to byte mode\n"
1756 " w change to word (2 byte) mode\n"
1757 " l change to long (4 byte) mode\n"
1758 " u change to doubleword (8 byte) mode\n"
1759 " m addr change current addr\n"
1760 " n toggle no-read flag\n"
1761 " r toggle byte reverse flag\n"
1762 " < count back up count bytes\n"
1763 " > count skip forward count bytes\n"
1764 " x exit this mode\n"
1770 int cmd, inc, i, nslash;
1772 unsigned char val[16];
1774 scanhex((void *)&adrs);
1777 printf(memex_help_string);
1783 while ((cmd = skipbl()) != '\n') {
1785 case 'b': size = 1; break;
1786 case 'w': size = 2; break;
1787 case 'l': size = 4; break;
1788 case 'd': size = 8; break;
1789 case 'r': brev = !brev; break;
1790 case 'n': mnoread = 1; break;
1791 case '.': mnoread = 0; break;
1800 n = mread(adrs, val, size);
1801 printf("%.16x%c", adrs, brev? 'r': ' ');
1806 for (i = 0; i < n; ++i)
1807 printf("%.2x", val[i]);
1808 for (; i < size; ++i)
1809 printf("%s", fault_chars[fault_type]);
1816 for (i = 0; i < size; ++i)
1817 val[i] = n >> (i * 8);
1820 mwrite(adrs, val, size);
1833 else if( n == '\'' )
1835 for (i = 0; i < size; ++i)
1836 val[i] = n >> (i * 8);
1839 mwrite(adrs, val, size);
1876 adrs -= 1 << nslash;
1880 adrs += 1 << nslash;
1884 adrs += 1 << -nslash;
1888 adrs -= 1 << -nslash;
1891 scanhex((void *)&adrs);
1910 printf(memex_subcmd_help_string);
1925 case 'n': c = '\n'; break;
1926 case 'r': c = '\r'; break;
1927 case 'b': c = '\b'; break;
1928 case 't': c = '\t'; break;
1933 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
1934 || ('a' <= (c) && (c) <= 'f') \
1935 || ('A' <= (c) && (c) <= 'F'))
1942 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
1944 scanhex((void *)&adrs);
1951 else if (nidump > MAX_DUMP)
1953 adrs += ppc_inst_dump(adrs, nidump, 1);
1959 else if (ndump > MAX_DUMP)
1961 prdump(adrs, ndump);
1968 prdump(unsigned long adrs, long ndump)
1970 long n, m, c, r, nr;
1971 unsigned char temp[16];
1973 for (n = ndump; n > 0;) {
1977 nr = mread(adrs, temp, r);
1979 for (m = 0; m < r; ++m) {
1980 if ((m & 7) == 0 && m > 0)
1983 printf("%.2x", temp[m]);
1985 printf("%s", fault_chars[fault_type]);
1992 for (m = 0; m < r; ++m) {
1995 putchar(' ' <= c && c <= '~'? c: '.');
2009 ppc_inst_dump(unsigned long adr, long count, int praddr)
2012 unsigned long first_adr;
2013 unsigned long inst, last_inst = 0;
2014 unsigned char val[4];
2017 for (first_adr = adr; count > 0; --count, adr += 4) {
2018 nr = mread(adr, val, 4);
2021 const char *x = fault_chars[fault_type];
2022 printf(REG" %s%s%s%s\n", adr, x, x, x, x);
2026 inst = GETWORD(val);
2027 if (adr > first_adr && inst == last_inst) {
2037 printf(REG" %.8x", adr, inst);
2039 print_insn_powerpc(inst, adr, 0); /* always returns 4 */
2042 return adr - first_adr;
2046 print_address(unsigned long addr)
2048 xmon_print_symbol(addr, "\t# ", "");
2053 * Memory operations - move, set, print differences
2055 static unsigned long mdest; /* destination address */
2056 static unsigned long msrc; /* source address */
2057 static unsigned long mval; /* byte value to set memory to */
2058 static unsigned long mcount; /* # bytes to affect */
2059 static unsigned long mdiffs; /* max # differences to print */
2064 scanhex((void *)&mdest);
2065 if( termch != '\n' )
2067 scanhex((void *)(cmd == 's'? &mval: &msrc));
2068 if( termch != '\n' )
2070 scanhex((void *)&mcount);
2073 memmove((void *)mdest, (void *)msrc, mcount);
2076 memset((void *)mdest, mval, mcount);
2079 if( termch != '\n' )
2081 scanhex((void *)&mdiffs);
2082 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2088 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2093 for( n = nb; n > 0; --n )
2094 if( *p1++ != *p2++ )
2095 if( ++prt <= maxpr )
2096 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2097 p1[-1], p2 - 1, p2[-1]);
2099 printf("Total of %d differences\n", prt);
2102 static unsigned mend;
2103 static unsigned mask;
2109 unsigned char val[4];
2112 scanhex((void *)&mdest);
2113 if (termch != '\n') {
2115 scanhex((void *)&mend);
2116 if (termch != '\n') {
2118 scanhex((void *)&mval);
2120 if (termch != '\n') termch = 0;
2121 scanhex((void *)&mask);
2125 for (a = mdest; a < mend; a += 4) {
2126 if (mread(a, val, 4) == 4
2127 && ((GETWORD(val) ^ mval) & mask) == 0) {
2128 printf("%.16x: %.16x\n", a, GETWORD(val));
2135 static unsigned long mskip = 0x1000;
2136 static unsigned long mlim = 0xffffffff;
2146 if (termch != '\n') termch = 0;
2148 if (termch != '\n') termch = 0;
2151 for (a = mdest; a < mlim; a += mskip) {
2152 ok = mread(a, &v, 1);
2154 printf("%.8x .. ", a);
2156 } else if (!ok && ook)
2157 printf("%.8x\n", a - mskip);
2163 printf("%.8x\n", a - mskip);
2168 unsigned long args[8];
2171 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2172 unsigned long, unsigned long, unsigned long,
2173 unsigned long, unsigned long, unsigned long);
2176 if (!scanhex(&adrs))
2180 for (i = 0; i < 8; ++i)
2182 for (i = 0; i < 8; ++i) {
2183 if (!scanhex(&args[i]) || termch == '\n')
2187 func = (callfunc_t) adrs;
2189 if (setjmp(bus_error_jmp) == 0) {
2190 catch_memory_errors = 1;
2192 ret = func(args[0], args[1], args[2], args[3],
2193 args[4], args[5], args[6], args[7]);
2195 printf("return value is %x\n", ret);
2197 printf("*** %x exception occurred\n", fault_except);
2199 catch_memory_errors = 0;
2202 /* Input scanning routines */
2213 while( c == ' ' || c == '\t' )
2219 static char *regnames[N_PTREGS] = {
2220 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2221 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2222 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2223 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2224 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2230 "trap", "dar", "dsisr", "res"
2234 scanhex(unsigned long *vp)
2241 /* parse register name */
2245 for (i = 0; i < sizeof(regname) - 1; ++i) {
2254 for (i = 0; i < N_PTREGS; ++i) {
2255 if (strcmp(regnames[i], regname) == 0) {
2256 if (xmon_regs == NULL) {
2257 printf("regs not available\n");
2260 *vp = ((unsigned long *)xmon_regs)[i];
2264 printf("invalid register name '%%%s'\n", regname);
2268 /* skip leading "0x" if any */
2282 } else if (c == '$') {
2284 for (i=0; i<63; i++) {
2294 if (setjmp(bus_error_jmp) == 0) {
2295 catch_memory_errors = 1;
2297 *vp = kallsyms_lookup_name(tmpstr);
2300 catch_memory_errors = 0;
2302 printf("unknown symbol '%s'\n", tmpstr);
2337 if( '0' <= c && c <= '9' )
2339 if( 'A' <= c && c <= 'F' )
2340 return c - ('A' - 10);
2341 if( 'a' <= c && c <= 'f' )
2342 return c - ('a' - 10);
2347 getstring(char *s, int size)
2358 } while( c != ' ' && c != '\t' && c != '\n' );
2363 static char line[256];
2364 static char *lineptr;
2375 if (lineptr == NULL || *lineptr == 0) {
2376 if (fgets(line, sizeof(line), stdin) == NULL) {
2386 take_input(char *str)
2395 int type = inchar();
2397 static char tmp[64];
2402 xmon_print_symbol(addr, ": ", "\n");
2407 if (setjmp(bus_error_jmp) == 0) {
2408 catch_memory_errors = 1;
2410 addr = kallsyms_lookup_name(tmp);
2412 printf("%s: %lx\n", tmp, addr);
2414 printf("Symbol '%s' not found.\n", tmp);
2417 catch_memory_errors = 0;
2424 /* Print an address in numeric and symbolic form (if possible) */
2425 static void xmon_print_symbol(unsigned long address, const char *mid,
2429 const char *name = NULL;
2430 unsigned long offset, size;
2432 printf(REG, address);
2433 if (setjmp(bus_error_jmp) == 0) {
2434 catch_memory_errors = 1;
2436 name = kallsyms_lookup(address, &size, &offset, &modname,
2439 /* wait a little while to see if we get a machine check */
2443 catch_memory_errors = 0;
2446 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2448 printf(" [%s]", modname);
2450 printf("%s", after);
2454 static void dump_slb(void)
2459 printf("SLB contents of cpu %x\n", smp_processor_id());
2461 for (i = 0; i < SLB_NUM_ENTRIES; i++) {
2462 asm volatile("slbmfee %0,%1" : "=r" (tmp) : "r" (i));
2463 printf("%02d %016lx ", i, tmp);
2465 asm volatile("slbmfev %0,%1" : "=r" (tmp) : "r" (i));
2466 printf("%016lx\n", tmp);
2470 static void dump_stab(void)
2473 unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2475 printf("Segment table contents of cpu %x\n", smp_processor_id());
2477 for (i = 0; i < PAGE_SIZE/16; i++) {
2484 printf("%03d %016lx ", i, a);
2485 printf("%016lx\n", b);
2490 void dump_segments(void)
2492 if (cpu_has_feature(CPU_FTR_SLB))
2499 #ifdef CONFIG_PPC_STD_MMU_32
2500 void dump_segments(void)
2505 for (i = 0; i < 16; ++i)
2506 printf(" %x", mfsrin(i));
2511 void xmon_init(int enable)
2515 __debugger_ipi = xmon_ipi;
2516 __debugger_bpt = xmon_bpt;
2517 __debugger_sstep = xmon_sstep;
2518 __debugger_iabr_match = xmon_iabr_match;
2519 __debugger_dabr_match = xmon_dabr_match;
2520 __debugger_fault_handler = xmon_fault_handler;
2523 __debugger_ipi = NULL;
2524 __debugger_bpt = NULL;
2525 __debugger_sstep = NULL;
2526 __debugger_iabr_match = NULL;
2527 __debugger_dabr_match = NULL;
2528 __debugger_fault_handler = NULL;