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 x exit monitor and recover\n\
214 X exit monitor and dont recover\n"
216 " u dump segment table or SLB\n"
218 #ifdef CONFIG_PPC_STD_MMU_32
219 " u dump segment registers\n"
226 static struct pt_regs *xmon_regs;
228 static inline void sync(void)
230 asm volatile("sync; isync");
233 static inline void store_inst(void *p)
235 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
238 static inline void cflush(void *p)
240 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
243 static inline void cinval(void *p)
245 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
249 * Disable surveillance (the service processor watchdog function)
250 * while we are in xmon.
251 * XXX we should re-enable it when we leave. :)
253 #define SURVEILLANCE_TOKEN 9000
255 static inline void disable_surveillance(void)
257 #ifdef CONFIG_PPC_PSERIES
258 /* Since this can't be a module, args should end up below 4GB. */
259 static struct rtas_args args;
262 * At this point we have got all the cpus we can into
263 * xmon, so there is hopefully no other cpu calling RTAS
264 * at the moment, even though we don't take rtas.lock.
265 * If we did try to take rtas.lock there would be a
266 * real possibility of deadlock.
268 args.token = rtas_token("set-indicator");
269 if (args.token == RTAS_UNKNOWN_SERVICE)
273 args.rets = &args.args[3];
274 args.args[0] = SURVEILLANCE_TOKEN;
277 enter_rtas(__pa(&args));
278 #endif /* CONFIG_PPC_PSERIES */
282 static int xmon_speaker;
284 static void get_output_lock(void)
286 int me = smp_processor_id() + 0x100;
287 int last_speaker = 0, prev;
290 if (xmon_speaker == me)
293 if (xmon_speaker == 0) {
294 last_speaker = cmpxchg(&xmon_speaker, 0, me);
295 if (last_speaker == 0)
299 while (xmon_speaker == last_speaker) {
302 /* hostile takeover */
303 prev = cmpxchg(&xmon_speaker, last_speaker, me);
304 if (prev == last_speaker)
311 static void release_output_lock(void)
317 int xmon_core(struct pt_regs *regs, int fromipi)
322 long recurse_jmp[JMP_BUF_LEN];
323 unsigned long offset;
327 unsigned long timeout;
331 mtmsr(msr & ~MSR_EE); /* disable interrupts */
333 bp = in_breakpoint_table(regs->nip, &offset);
335 regs->nip = bp->address + offset;
336 atomic_dec(&bp->ref_count);
342 cpu = smp_processor_id();
343 if (cpu_isset(cpu, cpus_in_xmon)) {
346 printf("cpu 0x%x: Exception %lx %s in xmon, "
347 "returning to main loop\n",
348 cpu, regs->trap, getvecname(TRAP(regs)));
349 release_output_lock();
350 longjmp(xmon_fault_jmp[cpu], 1);
353 if (setjmp(recurse_jmp) != 0) {
354 if (!in_xmon || !xmon_gate) {
356 printf("xmon: WARNING: bad recursive fault "
357 "on cpu 0x%x\n", cpu);
358 release_output_lock();
361 secondary = !(xmon_taken && cpu == xmon_owner);
365 xmon_fault_jmp[cpu] = recurse_jmp;
366 cpu_set(cpu, cpus_in_xmon);
369 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
370 bp = at_breakpoint(regs->nip);
371 if (bp || (regs->msr & MSR_RI) == 0)
378 printf("cpu 0x%x stopped at breakpoint 0x%x (",
380 xmon_print_symbol(regs->nip, " ", ")\n");
382 if ((regs->msr & MSR_RI) == 0)
383 printf("WARNING: exception is not recoverable, "
385 release_output_lock();
390 while (secondary && !xmon_gate) {
394 secondary = test_and_set_bit(0, &in_xmon);
399 if (!secondary && !xmon_gate) {
400 /* we are the first cpu to come in */
401 /* interrupt other cpu(s) */
402 int ncpus = num_online_cpus();
407 smp_send_debugger_break(MSG_ALL_BUT_SELF);
408 /* wait for other cpus to come in */
409 for (timeout = 100000000; timeout != 0; --timeout) {
410 if (cpus_weight(cpus_in_xmon) >= ncpus)
416 disable_surveillance();
417 /* for breakpoint or single step, print the current instr. */
418 if (bp || TRAP(regs) == 0xd00)
419 ppc_inst_dump(regs->nip, 1, 0);
420 printf("enter ? for help\n");
429 if (cpu == xmon_owner) {
430 if (!test_and_set_bit(0, &xmon_taken)) {
435 while (cpu == xmon_owner)
449 /* have switched to some other cpu */
454 cpu_clear(cpu, cpus_in_xmon);
455 xmon_fault_jmp[cpu] = NULL;
458 /* UP is simple... */
460 printf("Exception %lx %s in xmon, returning to main loop\n",
461 regs->trap, getvecname(TRAP(regs)));
462 longjmp(xmon_fault_jmp[0], 1);
464 if (setjmp(recurse_jmp) == 0) {
465 xmon_fault_jmp[0] = recurse_jmp;
469 bp = at_breakpoint(regs->nip);
471 printf("Stopped at breakpoint %x (", BP_NUM(bp));
472 xmon_print_symbol(regs->nip, " ", ")\n");
474 if ((regs->msr & MSR_RI) == 0)
475 printf("WARNING: exception is not recoverable, "
478 disable_surveillance();
479 /* for breakpoint or single step, print the current instr. */
480 if (bp || TRAP(regs) == 0xd00)
481 ppc_inst_dump(regs->nip, 1, 0);
482 printf("enter ? for help\n");
491 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
492 bp = at_breakpoint(regs->nip);
494 int stepped = emulate_step(regs, bp->instr[0]);
496 regs->nip = (unsigned long) &bp->instr[0];
497 atomic_inc(&bp->ref_count);
498 } else if (stepped < 0) {
499 printf("Couldn't single-step %s instruction\n",
500 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
507 mtmsr(msr); /* restore interrupt enable */
512 int xmon(struct pt_regs *excp)
517 xmon_save_regs(®s);
520 return xmon_core(excp, 0);
525 xmon_irq(int irq, void *d, struct pt_regs *regs)
528 local_irq_save(flags);
529 printf("Keyboard interrupt\n");
531 local_irq_restore(flags);
535 int xmon_bpt(struct pt_regs *regs)
538 unsigned long offset;
540 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
543 /* Are we at the trap at bp->instr[1] for some bp? */
544 bp = in_breakpoint_table(regs->nip, &offset);
545 if (bp != NULL && offset == 4) {
546 regs->nip = bp->address + 4;
547 atomic_dec(&bp->ref_count);
551 /* Are we at a breakpoint? */
552 bp = at_breakpoint(regs->nip);
561 int xmon_sstep(struct pt_regs *regs)
569 int xmon_dabr_match(struct pt_regs *regs)
571 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
573 if (dabr.enabled == 0)
579 int xmon_iabr_match(struct pt_regs *regs)
581 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
589 int xmon_ipi(struct pt_regs *regs)
592 if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
598 int xmon_fault_handler(struct pt_regs *regs)
601 unsigned long offset;
603 if (in_xmon && catch_memory_errors)
604 handle_fault(regs); /* doesn't return */
606 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
607 bp = in_breakpoint_table(regs->nip, &offset);
609 regs->nip = bp->address + offset;
610 atomic_dec(&bp->ref_count);
617 static struct bpt *at_breakpoint(unsigned long pc)
623 for (i = 0; i < NBPTS; ++i, ++bp)
624 if (bp->enabled && pc == bp->address)
629 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
633 off = nip - (unsigned long) bpts;
634 if (off >= sizeof(bpts))
636 off %= sizeof(struct bpt);
637 if (off != offsetof(struct bpt, instr[0])
638 && off != offsetof(struct bpt, instr[1]))
640 *offp = off - offsetof(struct bpt, instr[0]);
641 return (struct bpt *) (nip - off);
644 static struct bpt *new_breakpoint(unsigned long a)
649 bp = at_breakpoint(a);
653 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
654 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
656 bp->instr[1] = bpinstr;
657 store_inst(&bp->instr[1]);
662 printf("Sorry, no free breakpoints. Please clear one first.\n");
666 static void insert_bpts(void)
672 for (i = 0; i < NBPTS; ++i, ++bp) {
673 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
675 if (mread(bp->address, &bp->instr[0], 4) != 4) {
676 printf("Couldn't read instruction at %lx, "
677 "disabling breakpoint there\n", bp->address);
681 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
682 printf("Breakpoint at %lx is on an mtmsrd or rfid "
683 "instruction, disabling it\n", bp->address);
687 store_inst(&bp->instr[0]);
688 if (bp->enabled & BP_IABR)
690 if (mwrite(bp->address, &bpinstr, 4) != 4) {
691 printf("Couldn't write instruction at %lx, "
692 "disabling breakpoint there\n", bp->address);
693 bp->enabled &= ~BP_TRAP;
696 store_inst((void *)bp->address);
700 static void insert_cpu_bpts(void)
703 set_dabr(dabr.address | (dabr.enabled & 7));
704 if (iabr && cpu_has_feature(CPU_FTR_IABR))
705 mtspr(SPRN_IABR, iabr->address
706 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
709 static void remove_bpts(void)
716 for (i = 0; i < NBPTS; ++i, ++bp) {
717 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
719 if (mread(bp->address, &instr, 4) == 4
721 && mwrite(bp->address, &bp->instr, 4) != 4)
722 printf("Couldn't remove breakpoint at %lx\n",
725 store_inst((void *)bp->address);
729 static void remove_cpu_bpts(void)
732 if (cpu_has_feature(CPU_FTR_IABR))
736 /* Command interpreting routine */
737 static char *last_cmd;
740 cmds(struct pt_regs *excp)
748 printf("%x:", smp_processor_id());
749 #endif /* CONFIG_SMP */
756 if (last_cmd == NULL)
758 take_input(last_cmd);
792 prregs(excp); /* print regs */
833 #ifdef CONFIG_PPC_STD_MMU
839 printf("Unrecognized command: ");
841 if (' ' < cmd && cmd <= '~')
844 printf("\\x%x", cmd);
846 } while (cmd != '\n');
847 printf(" (type ? for help)\n");
854 * Step a single instruction.
855 * Some instructions we emulate, others we execute with MSR_SE set.
857 static int do_step(struct pt_regs *regs)
862 /* check we are in 64-bit kernel mode, translation enabled */
863 if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
864 if (mread(regs->nip, &instr, 4) == 4) {
865 stepped = emulate_step(regs, instr);
867 printf("Couldn't single-step %s instruction\n",
868 (IS_RFID(instr)? "rfid": "mtmsrd"));
872 regs->trap = 0xd00 | (regs->trap & 1);
873 printf("stepped to ");
874 xmon_print_symbol(regs->nip, " ", "\n");
875 ppc_inst_dump(regs->nip, 1, 0);
884 static void bootcmds(void)
890 ppc_md.restart(NULL);
897 static int cpu_cmd(void)
904 if (!scanhex(&cpu)) {
905 /* print cpus waiting or in xmon */
906 printf("cpus stopped:");
908 for (cpu = 0; cpu < NR_CPUS; ++cpu) {
909 if (cpu_isset(cpu, cpus_in_xmon)) {
915 printf("-%x", cpu - 1);
920 printf("-%x", NR_CPUS - 1);
924 /* try to switch to cpu specified */
925 if (!cpu_isset(cpu, cpus_in_xmon)) {
926 printf("cpu 0x%x isn't in xmon\n", cpu);
933 while (!xmon_taken) {
934 if (--timeout == 0) {
935 if (test_and_set_bit(0, &xmon_taken))
937 /* take control back */
939 xmon_owner = smp_processor_id();
940 printf("cpu %u didn't take control\n", cpu);
948 #endif /* CONFIG_SMP */
951 static unsigned short fcstab[256] = {
952 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
953 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
954 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
955 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
956 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
957 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
958 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
959 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
960 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
961 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
962 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
963 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
964 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
965 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
966 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
967 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
968 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
969 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
970 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
971 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
972 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
973 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
974 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
975 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
976 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
977 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
978 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
979 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
980 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
981 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
982 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
983 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
986 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
997 if (!scanhex(&ncsum))
1000 for (i = 0; i < ncsum; ++i) {
1001 if (mread(adrs+i, &v, 1) == 0) {
1002 printf("csum stopped at %x\n", adrs+i);
1007 printf("%x\n", fcs);
1011 * Check if this is a suitable place to put a breakpoint.
1013 static long check_bp_loc(unsigned long addr)
1018 if (addr < KERNELBASE) {
1019 printf("Breakpoints may only be placed at kernel addresses\n");
1022 if (!mread(addr, &instr, sizeof(instr))) {
1023 printf("Can't read instruction at address %lx\n", addr);
1026 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1027 printf("Breakpoints may not be placed on mtmsrd or rfid "
1034 static char *breakpoint_help_string =
1035 "Breakpoint command usage:\n"
1036 "b show breakpoints\n"
1037 "b <addr> [cnt] set breakpoint at given instr addr\n"
1038 "bc clear all breakpoints\n"
1039 "bc <n/addr> clear breakpoint number n or at addr\n"
1040 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1041 "bd <addr> [cnt] set hardware data breakpoint\n"
1051 const char badaddr[] = "Only kernel addresses are permitted "
1052 "for breakpoints\n";
1057 case 'd': /* bd - hardware data breakpoint */
1062 else if (cmd == 'w')
1068 if (scanhex(&dabr.address)) {
1069 if (dabr.address < KERNELBASE) {
1074 dabr.enabled = mode | BP_DABR;
1078 case 'i': /* bi - hardware instr breakpoint */
1079 if (!cpu_has_feature(CPU_FTR_IABR)) {
1080 printf("Hardware instruction breakpoint "
1081 "not supported on this cpu\n");
1085 iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1090 if (!check_bp_loc(a))
1092 bp = new_breakpoint(a);
1094 bp->enabled |= BP_IABR | BP_IABR_TE;
1102 /* clear all breakpoints */
1103 for (i = 0; i < NBPTS; ++i)
1104 bpts[i].enabled = 0;
1107 printf("All breakpoints cleared\n");
1111 if (a <= NBPTS && a >= 1) {
1112 /* assume a breakpoint number */
1113 bp = &bpts[a-1]; /* bp nums are 1 based */
1115 /* assume a breakpoint address */
1116 bp = at_breakpoint(a);
1118 printf("No breakpoint at %x\n", a);
1123 printf("Cleared breakpoint %x (", BP_NUM(bp));
1124 xmon_print_symbol(bp->address, " ", ")\n");
1132 printf(breakpoint_help_string);
1137 /* print all breakpoints */
1138 printf(" type address\n");
1140 printf(" data "REG" [", dabr.address);
1141 if (dabr.enabled & 1)
1143 if (dabr.enabled & 2)
1147 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1150 printf("%2x %s ", BP_NUM(bp),
1151 (bp->enabled & BP_IABR)? "inst": "trap");
1152 xmon_print_symbol(bp->address, " ", "\n");
1157 if (!check_bp_loc(a))
1159 bp = new_breakpoint(a);
1161 bp->enabled |= BP_TRAP;
1166 /* Very cheap human name for vector lookup. */
1168 const char *getvecname(unsigned long vec)
1173 case 0x100: ret = "(System Reset)"; break;
1174 case 0x200: ret = "(Machine Check)"; break;
1175 case 0x300: ret = "(Data Access)"; break;
1176 case 0x380: ret = "(Data SLB Access)"; break;
1177 case 0x400: ret = "(Instruction Access)"; break;
1178 case 0x480: ret = "(Instruction SLB Access)"; break;
1179 case 0x500: ret = "(Hardware Interrupt)"; break;
1180 case 0x600: ret = "(Alignment)"; break;
1181 case 0x700: ret = "(Program Check)"; break;
1182 case 0x800: ret = "(FPU Unavailable)"; break;
1183 case 0x900: ret = "(Decrementer)"; break;
1184 case 0xc00: ret = "(System Call)"; break;
1185 case 0xd00: ret = "(Single Step)"; break;
1186 case 0xf00: ret = "(Performance Monitor)"; break;
1187 case 0xf20: ret = "(Altivec Unavailable)"; break;
1188 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1194 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1195 unsigned long *endp)
1197 unsigned long size, offset;
1201 *startp = *endp = 0;
1204 if (setjmp(bus_error_jmp) == 0) {
1205 catch_memory_errors = 1;
1207 name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr);
1209 *startp = pc - offset;
1210 *endp = pc - offset + size;
1214 catch_memory_errors = 0;
1217 static int xmon_depth_to_print = 64;
1220 #define LRSAVE_OFFSET 0x10
1221 #define REG_FRAME_MARKER 0x7265677368657265ul /* "regshere" */
1222 #define MARKER_OFFSET 0x60
1223 #define REGS_OFFSET 0x70
1225 #define LRSAVE_OFFSET 4
1226 #define REG_FRAME_MARKER 0x72656773
1227 #define MARKER_OFFSET 8
1228 #define REGS_OFFSET 16
1231 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1235 unsigned long newsp;
1236 unsigned long marker;
1238 struct pt_regs regs;
1241 if (sp < PAGE_OFFSET) {
1243 printf("SP (%lx) is in userspace\n", sp);
1247 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1248 || !mread(sp, &newsp, sizeof(unsigned long))) {
1249 printf("Couldn't read stack frame at %lx\n", sp);
1254 * For the first stack frame, try to work out if
1255 * LR and/or the saved LR value in the bottommost
1256 * stack frame are valid.
1258 if ((pc | lr) != 0) {
1259 unsigned long fnstart, fnend;
1260 unsigned long nextip;
1263 get_function_bounds(pc, &fnstart, &fnend);
1266 mread(newsp + LRSAVE_OFFSET, &nextip,
1267 sizeof(unsigned long));
1269 if (lr < PAGE_OFFSET
1270 || (fnstart <= lr && lr < fnend))
1272 } else if (lr == nextip) {
1274 } else if (lr >= PAGE_OFFSET
1275 && !(fnstart <= lr && lr < fnend)) {
1276 printf("[link register ] ");
1277 xmon_print_symbol(lr, " ", "\n");
1280 printf("["REG"] ", sp);
1281 xmon_print_symbol(ip, " ", " (unreliable)\n");
1286 printf("["REG"] ", sp);
1287 xmon_print_symbol(ip, " ", "\n");
1290 /* Look for "regshere" marker to see if this is
1291 an exception frame. */
1292 if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1293 && marker == REG_FRAME_MARKER) {
1294 if (mread(sp + REGS_OFFSET, ®s, sizeof(regs))
1296 printf("Couldn't read registers at %lx\n",
1300 printf("--- Exception: %lx %s at ", regs.trap,
1301 getvecname(TRAP(®s)));
1304 xmon_print_symbol(pc, " ", "\n");
1311 } while (count++ < xmon_depth_to_print);
1314 static void backtrace(struct pt_regs *excp)
1319 xmon_show_stack(sp, 0, 0);
1321 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1325 static void print_bug_trap(struct pt_regs *regs)
1327 struct bug_entry *bug;
1330 if (regs->msr & MSR_PR)
1331 return; /* not in kernel */
1332 addr = regs->nip; /* address of trap instruction */
1333 if (addr < PAGE_OFFSET)
1335 bug = find_bug(regs->nip);
1338 if (bug->line & BUG_WARNING_TRAP)
1341 printf("kernel BUG in %s at %s:%d!\n",
1342 bug->function, bug->file, (unsigned int)bug->line);
1345 void excprint(struct pt_regs *fp)
1350 printf("cpu 0x%x: ", smp_processor_id());
1351 #endif /* CONFIG_SMP */
1354 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1356 xmon_print_symbol(fp->nip, ": ", "\n");
1358 printf(" lr: ", fp->link);
1359 xmon_print_symbol(fp->link, ": ", "\n");
1361 printf(" sp: %lx\n", fp->gpr[1]);
1362 printf(" msr: %lx\n", fp->msr);
1364 if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1365 printf(" dar: %lx\n", fp->dar);
1367 printf(" dsisr: %lx\n", fp->dsisr);
1370 printf(" current = 0x%lx\n", current);
1372 printf(" paca = 0x%lx\n", get_paca());
1375 printf(" pid = %ld, comm = %s\n",
1376 current->pid, current->comm);
1383 void prregs(struct pt_regs *fp)
1387 struct pt_regs regs;
1389 if (scanhex(&base)) {
1390 if (setjmp(bus_error_jmp) == 0) {
1391 catch_memory_errors = 1;
1393 regs = *(struct pt_regs *)base;
1397 catch_memory_errors = 0;
1398 printf("*** Error reading registers from "REG"\n",
1402 catch_memory_errors = 0;
1407 if (FULL_REGS(fp)) {
1408 for (n = 0; n < 16; ++n)
1409 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1410 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1412 for (n = 0; n < 7; ++n)
1413 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1414 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1417 for (n = 0; n < 32; ++n) {
1418 printf("R%.2d = %.8x%s", n, fp->gpr[n],
1419 (n & 3) == 3? "\n": " ");
1420 if (n == 12 && !FULL_REGS(fp)) {
1427 xmon_print_symbol(fp->nip, " ", "\n");
1429 xmon_print_symbol(fp->link, " ", "\n");
1430 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
1431 printf("ctr = "REG" xer = "REG" trap = %4lx\n",
1432 fp->ctr, fp->xer, fp->trap);
1434 if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1435 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1438 void cacheflush(void)
1441 unsigned long nflush;
1446 scanhex((void *)&adrs);
1451 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1452 if (setjmp(bus_error_jmp) == 0) {
1453 catch_memory_errors = 1;
1457 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1458 cflush((void *) adrs);
1460 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1461 cinval((void *) adrs);
1464 /* wait a little while to see if we get a machine check */
1467 catch_memory_errors = 0;
1473 unsigned int instrs[2];
1474 unsigned long (*code)(void);
1475 unsigned long opd[3];
1476 unsigned long ret = -1UL;
1478 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1479 instrs[1] = 0x4e800020;
1480 opd[0] = (unsigned long)instrs;
1484 store_inst(instrs+1);
1485 code = (unsigned long (*)(void)) opd;
1487 if (setjmp(bus_error_jmp) == 0) {
1488 catch_memory_errors = 1;
1494 /* wait a little while to see if we get a machine check */
1503 write_spr(int n, unsigned long val)
1505 unsigned int instrs[2];
1506 unsigned long (*code)(unsigned long);
1507 unsigned long opd[3];
1509 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1510 instrs[1] = 0x4e800020;
1511 opd[0] = (unsigned long)instrs;
1515 store_inst(instrs+1);
1516 code = (unsigned long (*)(unsigned long)) opd;
1518 if (setjmp(bus_error_jmp) == 0) {
1519 catch_memory_errors = 1;
1525 /* wait a little while to see if we get a machine check */
1531 static unsigned long regno;
1532 extern char exc_prolog;
1533 extern char dec_exc;
1535 void super_regs(void)
1539 #ifdef CONFIG_PPC_ISERIES
1540 struct paca_struct *ptrPaca = NULL;
1541 struct lppaca *ptrLpPaca = NULL;
1542 struct ItLpRegSave *ptrLpRegSave = NULL;
1547 unsigned long sp, toc;
1548 asm("mr %0,1" : "=r" (sp) :);
1549 asm("mr %0,2" : "=r" (toc) :);
1551 printf("msr = "REG" sprg0= "REG"\n",
1552 mfmsr(), mfspr(SPRN_SPRG0));
1553 printf("pvr = "REG" sprg1= "REG"\n",
1554 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
1555 printf("dec = "REG" sprg2= "REG"\n",
1556 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1557 printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1558 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
1559 #ifdef CONFIG_PPC_ISERIES
1560 // Dump out relevant Paca data areas.
1562 ptrPaca = get_paca();
1564 printf(" Local Processor Control Area (LpPaca): \n");
1565 ptrLpPaca = ptrPaca->lppaca_ptr;
1566 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1567 ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
1568 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1569 ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
1570 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
1572 printf(" Local Processor Register Save Area (LpRegSave): \n");
1573 ptrLpRegSave = ptrPaca->reg_save_ptr;
1574 printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n",
1575 ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
1576 printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n",
1577 ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
1578 printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n",
1579 ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
1588 val = read_spr(regno);
1590 write_spr(regno, val);
1593 printf("spr %lx = %lx\n", regno, read_spr(regno));
1600 * Stuff for reading and writing memory safely
1603 mread(unsigned long adrs, void *buf, int size)
1609 if (setjmp(bus_error_jmp) == 0) {
1610 catch_memory_errors = 1;
1616 *(u16 *)q = *(u16 *)p;
1619 *(u32 *)q = *(u32 *)p;
1622 *(u64 *)q = *(u64 *)p;
1625 for( ; n < size; ++n) {
1631 /* wait a little while to see if we get a machine check */
1635 catch_memory_errors = 0;
1640 mwrite(unsigned long adrs, void *buf, int size)
1646 if (setjmp(bus_error_jmp) == 0) {
1647 catch_memory_errors = 1;
1653 *(u16 *)p = *(u16 *)q;
1656 *(u32 *)p = *(u32 *)q;
1659 *(u64 *)p = *(u64 *)q;
1662 for ( ; n < size; ++n) {
1668 /* wait a little while to see if we get a machine check */
1672 printf("*** Error writing address %x\n", adrs + n);
1674 catch_memory_errors = 0;
1678 static int fault_type;
1679 static int fault_except;
1680 static char *fault_chars[] = { "--", "**", "##" };
1682 static int handle_fault(struct pt_regs *regs)
1684 fault_except = TRAP(regs);
1685 switch (TRAP(regs)) {
1697 longjmp(bus_error_jmp, 1);
1702 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1705 byterev(unsigned char *val, int size)
1711 SWAP(val[0], val[1], t);
1714 SWAP(val[0], val[3], t);
1715 SWAP(val[1], val[2], t);
1717 case 8: /* is there really any use for this? */
1718 SWAP(val[0], val[7], t);
1719 SWAP(val[1], val[6], t);
1720 SWAP(val[2], val[5], t);
1721 SWAP(val[3], val[4], t);
1729 static char *memex_help_string =
1730 "Memory examine command usage:\n"
1731 "m [addr] [flags] examine/change memory\n"
1732 " addr is optional. will start where left off.\n"
1733 " flags may include chars from this set:\n"
1734 " b modify by bytes (default)\n"
1735 " w modify by words (2 byte)\n"
1736 " l modify by longs (4 byte)\n"
1737 " d modify by doubleword (8 byte)\n"
1738 " r toggle reverse byte order mode\n"
1739 " n do not read memory (for i/o spaces)\n"
1740 " . ok to read (default)\n"
1741 "NOTE: flags are saved as defaults\n"
1744 static char *memex_subcmd_help_string =
1745 "Memory examine subcommands:\n"
1746 " hexval write this val to current location\n"
1747 " 'string' write chars from string to this location\n"
1748 " ' increment address\n"
1749 " ^ decrement address\n"
1750 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1751 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1752 " ` clear no-read flag\n"
1753 " ; stay at this addr\n"
1754 " v change to byte mode\n"
1755 " w change to word (2 byte) mode\n"
1756 " l change to long (4 byte) mode\n"
1757 " u change to doubleword (8 byte) mode\n"
1758 " m addr change current addr\n"
1759 " n toggle no-read flag\n"
1760 " r toggle byte reverse flag\n"
1761 " < count back up count bytes\n"
1762 " > count skip forward count bytes\n"
1763 " x exit this mode\n"
1769 int cmd, inc, i, nslash;
1771 unsigned char val[16];
1773 scanhex((void *)&adrs);
1776 printf(memex_help_string);
1782 while ((cmd = skipbl()) != '\n') {
1784 case 'b': size = 1; break;
1785 case 'w': size = 2; break;
1786 case 'l': size = 4; break;
1787 case 'd': size = 8; break;
1788 case 'r': brev = !brev; break;
1789 case 'n': mnoread = 1; break;
1790 case '.': mnoread = 0; break;
1799 n = mread(adrs, val, size);
1800 printf("%.16x%c", adrs, brev? 'r': ' ');
1805 for (i = 0; i < n; ++i)
1806 printf("%.2x", val[i]);
1807 for (; i < size; ++i)
1808 printf("%s", fault_chars[fault_type]);
1815 for (i = 0; i < size; ++i)
1816 val[i] = n >> (i * 8);
1819 mwrite(adrs, val, size);
1832 else if( n == '\'' )
1834 for (i = 0; i < size; ++i)
1835 val[i] = n >> (i * 8);
1838 mwrite(adrs, val, size);
1875 adrs -= 1 << nslash;
1879 adrs += 1 << nslash;
1883 adrs += 1 << -nslash;
1887 adrs -= 1 << -nslash;
1890 scanhex((void *)&adrs);
1909 printf(memex_subcmd_help_string);
1924 case 'n': c = '\n'; break;
1925 case 'r': c = '\r'; break;
1926 case 'b': c = '\b'; break;
1927 case 't': c = '\t'; break;
1932 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
1933 || ('a' <= (c) && (c) <= 'f') \
1934 || ('A' <= (c) && (c) <= 'F'))
1941 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
1943 scanhex((void *)&adrs);
1950 else if (nidump > MAX_DUMP)
1952 adrs += ppc_inst_dump(adrs, nidump, 1);
1958 else if (ndump > MAX_DUMP)
1960 prdump(adrs, ndump);
1967 prdump(unsigned long adrs, long ndump)
1969 long n, m, c, r, nr;
1970 unsigned char temp[16];
1972 for (n = ndump; n > 0;) {
1976 nr = mread(adrs, temp, r);
1978 for (m = 0; m < r; ++m) {
1979 if ((m & 7) == 0 && m > 0)
1982 printf("%.2x", temp[m]);
1984 printf("%s", fault_chars[fault_type]);
1991 for (m = 0; m < r; ++m) {
1994 putchar(' ' <= c && c <= '~'? c: '.');
2008 ppc_inst_dump(unsigned long adr, long count, int praddr)
2011 unsigned long first_adr;
2012 unsigned long inst, last_inst = 0;
2013 unsigned char val[4];
2016 for (first_adr = adr; count > 0; --count, adr += 4) {
2017 nr = mread(adr, val, 4);
2020 const char *x = fault_chars[fault_type];
2021 printf(REG" %s%s%s%s\n", adr, x, x, x, x);
2025 inst = GETWORD(val);
2026 if (adr > first_adr && inst == last_inst) {
2036 printf(REG" %.8x", adr, inst);
2038 print_insn_powerpc(inst, adr, 0); /* always returns 4 */
2041 return adr - first_adr;
2045 print_address(unsigned long addr)
2047 xmon_print_symbol(addr, "\t# ", "");
2052 * Memory operations - move, set, print differences
2054 static unsigned long mdest; /* destination address */
2055 static unsigned long msrc; /* source address */
2056 static unsigned long mval; /* byte value to set memory to */
2057 static unsigned long mcount; /* # bytes to affect */
2058 static unsigned long mdiffs; /* max # differences to print */
2063 scanhex((void *)&mdest);
2064 if( termch != '\n' )
2066 scanhex((void *)(cmd == 's'? &mval: &msrc));
2067 if( termch != '\n' )
2069 scanhex((void *)&mcount);
2072 memmove((void *)mdest, (void *)msrc, mcount);
2075 memset((void *)mdest, mval, mcount);
2078 if( termch != '\n' )
2080 scanhex((void *)&mdiffs);
2081 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2087 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2092 for( n = nb; n > 0; --n )
2093 if( *p1++ != *p2++ )
2094 if( ++prt <= maxpr )
2095 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2096 p1[-1], p2 - 1, p2[-1]);
2098 printf("Total of %d differences\n", prt);
2101 static unsigned mend;
2102 static unsigned mask;
2108 unsigned char val[4];
2111 scanhex((void *)&mdest);
2112 if (termch != '\n') {
2114 scanhex((void *)&mend);
2115 if (termch != '\n') {
2117 scanhex((void *)&mval);
2119 if (termch != '\n') termch = 0;
2120 scanhex((void *)&mask);
2124 for (a = mdest; a < mend; a += 4) {
2125 if (mread(a, val, 4) == 4
2126 && ((GETWORD(val) ^ mval) & mask) == 0) {
2127 printf("%.16x: %.16x\n", a, GETWORD(val));
2134 static unsigned long mskip = 0x1000;
2135 static unsigned long mlim = 0xffffffff;
2145 if (termch != '\n') termch = 0;
2147 if (termch != '\n') termch = 0;
2150 for (a = mdest; a < mlim; a += mskip) {
2151 ok = mread(a, &v, 1);
2153 printf("%.8x .. ", a);
2155 } else if (!ok && ook)
2156 printf("%.8x\n", a - mskip);
2162 printf("%.8x\n", a - mskip);
2167 unsigned long args[8];
2170 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2171 unsigned long, unsigned long, unsigned long,
2172 unsigned long, unsigned long, unsigned long);
2175 if (!scanhex(&adrs))
2179 for (i = 0; i < 8; ++i)
2181 for (i = 0; i < 8; ++i) {
2182 if (!scanhex(&args[i]) || termch == '\n')
2186 func = (callfunc_t) adrs;
2188 if (setjmp(bus_error_jmp) == 0) {
2189 catch_memory_errors = 1;
2191 ret = func(args[0], args[1], args[2], args[3],
2192 args[4], args[5], args[6], args[7]);
2194 printf("return value is %x\n", ret);
2196 printf("*** %x exception occurred\n", fault_except);
2198 catch_memory_errors = 0;
2201 /* Input scanning routines */
2212 while( c == ' ' || c == '\t' )
2218 static char *regnames[N_PTREGS] = {
2219 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2220 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2221 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2222 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2223 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2229 "trap", "dar", "dsisr", "res"
2233 scanhex(unsigned long *vp)
2240 /* parse register name */
2244 for (i = 0; i < sizeof(regname) - 1; ++i) {
2253 for (i = 0; i < N_PTREGS; ++i) {
2254 if (strcmp(regnames[i], regname) == 0) {
2255 if (xmon_regs == NULL) {
2256 printf("regs not available\n");
2259 *vp = ((unsigned long *)xmon_regs)[i];
2263 printf("invalid register name '%%%s'\n", regname);
2267 /* skip leading "0x" if any */
2281 } else if (c == '$') {
2283 for (i=0; i<63; i++) {
2293 if (setjmp(bus_error_jmp) == 0) {
2294 catch_memory_errors = 1;
2296 *vp = kallsyms_lookup_name(tmpstr);
2299 catch_memory_errors = 0;
2301 printf("unknown symbol '%s'\n", tmpstr);
2336 if( '0' <= c && c <= '9' )
2338 if( 'A' <= c && c <= 'F' )
2339 return c - ('A' - 10);
2340 if( 'a' <= c && c <= 'f' )
2341 return c - ('a' - 10);
2346 getstring(char *s, int size)
2357 } while( c != ' ' && c != '\t' && c != '\n' );
2362 static char line[256];
2363 static char *lineptr;
2374 if (lineptr == NULL || *lineptr == 0) {
2375 if (fgets(line, sizeof(line), stdin) == NULL) {
2385 take_input(char *str)
2394 int type = inchar();
2396 static char tmp[64];
2401 xmon_print_symbol(addr, ": ", "\n");
2406 if (setjmp(bus_error_jmp) == 0) {
2407 catch_memory_errors = 1;
2409 addr = kallsyms_lookup_name(tmp);
2411 printf("%s: %lx\n", tmp, addr);
2413 printf("Symbol '%s' not found.\n", tmp);
2416 catch_memory_errors = 0;
2423 /* Print an address in numeric and symbolic form (if possible) */
2424 static void xmon_print_symbol(unsigned long address, const char *mid,
2428 const char *name = NULL;
2429 unsigned long offset, size;
2431 printf(REG, address);
2432 if (setjmp(bus_error_jmp) == 0) {
2433 catch_memory_errors = 1;
2435 name = kallsyms_lookup(address, &size, &offset, &modname,
2438 /* wait a little while to see if we get a machine check */
2442 catch_memory_errors = 0;
2445 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2447 printf(" [%s]", modname);
2449 printf("%s", after);
2453 static void dump_slb(void)
2458 printf("SLB contents of cpu %x\n", smp_processor_id());
2460 for (i = 0; i < SLB_NUM_ENTRIES; i++) {
2461 asm volatile("slbmfee %0,%1" : "=r" (tmp) : "r" (i));
2462 printf("%02d %016lx ", i, tmp);
2464 asm volatile("slbmfev %0,%1" : "=r" (tmp) : "r" (i));
2465 printf("%016lx\n", tmp);
2469 static void dump_stab(void)
2472 unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2474 printf("Segment table contents of cpu %x\n", smp_processor_id());
2476 for (i = 0; i < PAGE_SIZE/16; i++) {
2483 printf("%03d %016lx ", i, a);
2484 printf("%016lx\n", b);
2489 void dump_segments(void)
2491 if (cpu_has_feature(CPU_FTR_SLB))
2498 #ifdef CONFIG_PPC_STD_MMU_32
2499 void dump_segments(void)
2504 for (i = 0; i < 16; ++i)
2505 printf(" %x", mfsrin(i));
2510 void xmon_init(int enable)
2514 __debugger_ipi = xmon_ipi;
2515 __debugger_bpt = xmon_bpt;
2516 __debugger_sstep = xmon_sstep;
2517 __debugger_iabr_match = xmon_iabr_match;
2518 __debugger_dabr_match = xmon_dabr_match;
2519 __debugger_fault_handler = xmon_fault_handler;
2522 __debugger_ipi = NULL;
2523 __debugger_bpt = NULL;
2524 __debugger_sstep = NULL;
2525 __debugger_iabr_match = NULL;
2526 __debugger_dabr_match = NULL;
2527 __debugger_fault_handler = NULL;