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>
21 #include <asm/ptrace.h>
22 #include <asm/string.h>
24 #include <asm/machdep.h>
25 #include <asm/processor.h>
26 #include <asm/pgtable.h>
28 #include <asm/mmu_context.h>
30 #include <asm/ppcdebug.h>
31 #include <asm/cputable.h>
33 #include <asm/sstep.h>
39 #define scanhex xmon_scanhex
40 #define skipbl xmon_skipbl
43 cpumask_t cpus_in_xmon = CPU_MASK_NONE;
44 static unsigned long xmon_taken = 1;
45 static int xmon_owner;
47 #endif /* CONFIG_SMP */
49 static unsigned long in_xmon = 0;
51 static unsigned long adrs;
53 #define MAX_DUMP (128 * 1024)
54 static unsigned long ndump = 64;
55 static unsigned long nidump = 16;
56 static unsigned long ncsum = 4096;
58 static char tmpstr[128];
60 #define JMP_BUF_LEN (184/sizeof(long))
61 static long bus_error_jmp[JMP_BUF_LEN];
62 static int catch_memory_errors;
63 static long *xmon_fault_jmp[NR_CPUS];
64 #define setjmp xmon_setjmp
65 #define longjmp xmon_longjmp
67 /* Breakpoint stuff */
69 unsigned long address;
70 unsigned int instr[2];
76 /* Bits in bpt.enabled */
77 #define BP_IABR_TE 1 /* IABR translation enabled */
83 static struct bpt bpts[NBPTS];
84 static struct bpt dabr;
85 static struct bpt *iabr;
86 static unsigned bpinstr = 0x7fe00008; /* trap */
88 #define BP_NUM(bp) ((bp) - bpts + 1)
91 static int cmds(struct pt_regs *);
92 static int mread(unsigned long, void *, int);
93 static int mwrite(unsigned long, void *, int);
94 static int handle_fault(struct pt_regs *);
95 static void byterev(unsigned char *, int);
96 static void memex(void);
97 static int bsesc(void);
98 static void dump(void);
99 static void prdump(unsigned long, long);
100 static int ppc_inst_dump(unsigned long, long, int);
101 void print_address(unsigned long);
102 static void backtrace(struct pt_regs *);
103 static void excprint(struct pt_regs *);
104 static void prregs(struct pt_regs *);
105 static void memops(int);
106 static void memlocate(void);
107 static void memzcan(void);
108 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
110 int scanhex(unsigned long *valp);
111 static void scannl(void);
112 static int hexdigit(int);
113 void getstring(char *, int);
114 static void flush_input(void);
115 static int inchar(void);
116 static void take_input(char *);
117 static unsigned long read_spr(int);
118 static void write_spr(int, unsigned long);
119 static void super_regs(void);
120 static void remove_bpts(void);
121 static void insert_bpts(void);
122 static void remove_cpu_bpts(void);
123 static void insert_cpu_bpts(void);
124 static struct bpt *at_breakpoint(unsigned long pc);
125 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
126 static int do_step(struct pt_regs *);
127 static void bpt_cmds(void);
128 static void cacheflush(void);
129 static int cpu_cmd(void);
130 static void csum(void);
131 static void bootcmds(void);
132 void dump_segments(void);
133 static void symbol_lookup(void);
134 static void xmon_print_symbol(unsigned long address, const char *mid,
136 static const char *getvecname(unsigned long vec);
138 static void debug_trace(void);
140 extern int print_insn_powerpc(unsigned long, unsigned long, int);
141 extern void printf(const char *fmt, ...);
142 extern void xmon_vfprintf(void *f, const char *fmt, va_list ap);
143 extern int xmon_putc(int c, void *f);
144 extern int putchar(int ch);
145 extern int xmon_read_poll(void);
146 extern int setjmp(long *);
147 extern void longjmp(long *, int);
148 extern unsigned long _ASR;
150 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
152 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
153 || ('a' <= (c) && (c) <= 'f') \
154 || ('A' <= (c) && (c) <= 'F'))
155 #define isalnum(c) (('0' <= (c) && (c) <= '9') \
156 || ('a' <= (c) && (c) <= 'z') \
157 || ('A' <= (c) && (c) <= 'Z'))
158 #define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
160 static char *help_string = "\
162 b show breakpoints\n\
163 bd set data breakpoint\n\
164 bi set instruction breakpoint\n\
165 bc clear breakpoint\n"
168 c print cpus stopped in xmon\n\
169 c# try to switch to cpu number h (in hex)\n"
174 di dump instructions\n\
175 df dump float values\n\
176 dd dump double values\n\
177 e print exception information\n\
179 la lookup symbol+offset of specified address\n\
180 ls lookup address of specified symbol\n\
181 m examine/change memory\n\
182 mm move a block of memory\n\
183 ms set a block of memory\n\
184 md compare two blocks of memory\n\
185 ml locate a block of memory\n\
186 mz zero a block of memory\n\
187 mi show information about memory allocation\n\
188 p show the task list\n\
191 S print special registers\n\
193 T Enable/Disable PPCDBG flags\n\
194 x exit monitor and recover\n\
195 X exit monitor and dont recover\n\
196 u dump segment table or SLB\n\
203 static struct pt_regs *xmon_regs;
205 extern inline void sync(void)
207 asm volatile("sync; isync");
210 /* (Ref: 64-bit PowerPC ELF ABI Spplement; Ian Lance Taylor, Zembu Labs).
211 A PPC stack frame looks like this:
218 Parameter save area (SP+48)
219 TOC save area (SP+40)
220 link editor doubleword (SP+32)
221 compiler doubleword (SP+24)
226 Note that the LR (ret addr) may not be saved in the current frame if
227 no functions have been called from the current function.
231 * Disable surveillance (the service processor watchdog function)
232 * while we are in xmon.
233 * XXX we should re-enable it when we leave. :)
235 #define SURVEILLANCE_TOKEN 9000
237 static inline void disable_surveillance(void)
239 #ifdef CONFIG_PPC_PSERIES
240 /* Since this can't be a module, args should end up below 4GB. */
241 static struct rtas_args args;
244 * At this point we have got all the cpus we can into
245 * xmon, so there is hopefully no other cpu calling RTAS
246 * at the moment, even though we don't take rtas.lock.
247 * If we did try to take rtas.lock there would be a
248 * real possibility of deadlock.
250 args.token = rtas_token("set-indicator");
251 if (args.token == RTAS_UNKNOWN_SERVICE)
255 args.rets = &args.args[3];
256 args.args[0] = SURVEILLANCE_TOKEN;
259 enter_rtas(__pa(&args));
260 #endif /* CONFIG_PPC_PSERIES */
264 static int xmon_speaker;
266 static void get_output_lock(void)
268 int me = smp_processor_id() + 0x100;
269 int last_speaker = 0, prev;
272 if (xmon_speaker == me)
275 if (xmon_speaker == 0) {
276 last_speaker = cmpxchg(&xmon_speaker, 0, me);
277 if (last_speaker == 0)
281 while (xmon_speaker == last_speaker) {
284 /* hostile takeover */
285 prev = cmpxchg(&xmon_speaker, last_speaker, me);
286 if (prev == last_speaker)
293 static void release_output_lock(void)
299 int xmon_core(struct pt_regs *regs, int fromipi)
304 long recurse_jmp[JMP_BUF_LEN];
305 unsigned long offset;
309 unsigned long timeout;
313 set_msrd(msr & ~MSR_EE); /* disable interrupts */
315 bp = in_breakpoint_table(regs->nip, &offset);
317 regs->nip = bp->address + offset;
318 atomic_dec(&bp->ref_count);
324 cpu = smp_processor_id();
325 if (cpu_isset(cpu, cpus_in_xmon)) {
328 printf("cpu 0x%x: Exception %lx %s in xmon, "
329 "returning to main loop\n",
330 cpu, regs->trap, getvecname(TRAP(regs)));
331 longjmp(xmon_fault_jmp[cpu], 1);
334 if (setjmp(recurse_jmp) != 0) {
335 if (!in_xmon || !xmon_gate) {
336 printf("xmon: WARNING: bad recursive fault "
337 "on cpu 0x%x\n", cpu);
340 secondary = !(xmon_taken && cpu == xmon_owner);
344 xmon_fault_jmp[cpu] = recurse_jmp;
345 cpu_set(cpu, cpus_in_xmon);
348 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
349 bp = at_breakpoint(regs->nip);
350 if (bp || (regs->msr & MSR_RI) == 0)
357 printf("cpu 0x%x stopped at breakpoint 0x%x (",
359 xmon_print_symbol(regs->nip, " ", ")\n");
361 if ((regs->msr & MSR_RI) == 0)
362 printf("WARNING: exception is not recoverable, "
364 release_output_lock();
369 while (secondary && !xmon_gate) {
373 secondary = test_and_set_bit(0, &in_xmon);
378 if (!secondary && !xmon_gate) {
379 /* we are the first cpu to come in */
380 /* interrupt other cpu(s) */
381 int ncpus = num_online_cpus();
386 smp_send_debugger_break(MSG_ALL_BUT_SELF);
387 /* wait for other cpus to come in */
388 for (timeout = 100000000; timeout != 0; --timeout) {
389 if (cpus_weight(cpus_in_xmon) >= ncpus)
395 disable_surveillance();
396 /* for breakpoint or single step, print the current instr. */
397 if (bp || TRAP(regs) == 0xd00)
398 ppc_inst_dump(regs->nip, 1, 0);
399 printf("enter ? for help\n");
408 if (cpu == xmon_owner) {
409 if (!test_and_set_bit(0, &xmon_taken)) {
414 while (cpu == xmon_owner)
428 /* have switched to some other cpu */
433 cpu_clear(cpu, cpus_in_xmon);
434 xmon_fault_jmp[cpu] = NULL;
437 /* UP is simple... */
439 printf("Exception %lx %s in xmon, returning to main loop\n",
440 regs->trap, getvecname(TRAP(regs)));
441 longjmp(xmon_fault_jmp[0], 1);
443 if (setjmp(recurse_jmp) == 0) {
444 xmon_fault_jmp[0] = recurse_jmp;
448 bp = at_breakpoint(regs->nip);
450 printf("Stopped at breakpoint %x (", BP_NUM(bp));
451 xmon_print_symbol(regs->nip, " ", ")\n");
453 if ((regs->msr & MSR_RI) == 0)
454 printf("WARNING: exception is not recoverable, "
457 disable_surveillance();
458 /* for breakpoint or single step, print the current instr. */
459 if (bp || TRAP(regs) == 0xd00)
460 ppc_inst_dump(regs->nip, 1, 0);
461 printf("enter ? for help\n");
470 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
471 bp = at_breakpoint(regs->nip);
473 int stepped = emulate_step(regs, bp->instr[0]);
475 regs->nip = (unsigned long) &bp->instr[0];
476 atomic_inc(&bp->ref_count);
477 } else if (stepped < 0) {
478 printf("Couldn't single-step %s instruction\n",
479 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
486 set_msrd(msr); /* restore interrupt enable */
491 int xmon(struct pt_regs *excp)
496 /* Ok, grab regs as they are now.
497 This won't do a particularily good job because the
498 prologue has already been executed.
499 ToDo: We could reach back into the callers save
500 area to do a better job of representing the
503 asm volatile ("std 0,0(%0)\n\
534 std 31,248(%0)" : : "b" (®s));
536 regs.nip = regs.link = ((unsigned long *)(regs.gpr[1]))[2];
537 regs.msr = get_msr();
538 regs.ctr = get_ctr();
539 regs.xer = get_xer();
544 return xmon_core(excp, 0);
547 int xmon_bpt(struct pt_regs *regs)
550 unsigned long offset;
552 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
555 /* Are we at the trap at bp->instr[1] for some bp? */
556 bp = in_breakpoint_table(regs->nip, &offset);
557 if (bp != NULL && offset == 4) {
558 regs->nip = bp->address + 4;
559 atomic_dec(&bp->ref_count);
563 /* Are we at a breakpoint? */
564 bp = at_breakpoint(regs->nip);
573 int xmon_sstep(struct pt_regs *regs)
581 int xmon_dabr_match(struct pt_regs *regs)
583 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
589 int xmon_iabr_match(struct pt_regs *regs)
591 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
599 int xmon_ipi(struct pt_regs *regs)
602 if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
608 int xmon_fault_handler(struct pt_regs *regs)
611 unsigned long offset;
613 if (in_xmon && catch_memory_errors)
614 handle_fault(regs); /* doesn't return */
616 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
617 bp = in_breakpoint_table(regs->nip, &offset);
619 regs->nip = bp->address + offset;
620 atomic_dec(&bp->ref_count);
627 /* On systems with a hypervisor, we can't set the DABR
628 (data address breakpoint register) directly. */
629 static void set_controlled_dabr(unsigned long val)
631 #ifdef CONFIG_PPC_PSERIES
632 if (systemcfg->platform == PLATFORM_PSERIES_LPAR) {
633 int rc = plpar_hcall_norets(H_SET_DABR, val);
635 xmon_printf("Warning: setting DABR failed (%d)\n", rc);
641 static struct bpt *at_breakpoint(unsigned long pc)
647 for (i = 0; i < NBPTS; ++i, ++bp)
648 if (bp->enabled && pc == bp->address)
653 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
657 off = nip - (unsigned long) bpts;
658 if (off >= sizeof(bpts))
660 off %= sizeof(struct bpt);
661 if (off != offsetof(struct bpt, instr[0])
662 && off != offsetof(struct bpt, instr[1]))
664 *offp = off - offsetof(struct bpt, instr[0]);
665 return (struct bpt *) (nip - off);
668 static struct bpt *new_breakpoint(unsigned long a)
673 bp = at_breakpoint(a);
677 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
678 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
680 bp->instr[1] = bpinstr;
681 store_inst(&bp->instr[1]);
686 printf("Sorry, no free breakpoints. Please clear one first.\n");
690 static void insert_bpts(void)
696 for (i = 0; i < NBPTS; ++i, ++bp) {
697 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
699 if (mread(bp->address, &bp->instr[0], 4) != 4) {
700 printf("Couldn't read instruction at %lx, "
701 "disabling breakpoint there\n", bp->address);
705 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
706 printf("Breakpoint at %lx is on an mtmsrd or rfid "
707 "instruction, disabling it\n", bp->address);
711 store_inst(&bp->instr[0]);
712 if (bp->enabled & BP_IABR)
714 if (mwrite(bp->address, &bpinstr, 4) != 4) {
715 printf("Couldn't write instruction at %lx, "
716 "disabling breakpoint there\n", bp->address);
717 bp->enabled &= ~BP_TRAP;
720 store_inst((void *)bp->address);
724 static void insert_cpu_bpts(void)
727 set_controlled_dabr(dabr.address | (dabr.enabled & 7));
728 if (iabr && (cur_cpu_spec->cpu_features & CPU_FTR_IABR))
729 set_iabr(iabr->address
730 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
733 static void remove_bpts(void)
740 for (i = 0; i < NBPTS; ++i, ++bp) {
741 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
743 if (mread(bp->address, &instr, 4) == 4
745 && mwrite(bp->address, &bp->instr, 4) != 4)
746 printf("Couldn't remove breakpoint at %lx\n",
749 store_inst((void *)bp->address);
753 static void remove_cpu_bpts(void)
755 set_controlled_dabr(0);
756 if ((cur_cpu_spec->cpu_features & CPU_FTR_IABR))
760 /* Command interpreting routine */
761 static char *last_cmd;
764 cmds(struct pt_regs *excp)
772 printf("%x:", smp_processor_id());
773 #endif /* CONFIG_SMP */
780 if (last_cmd == NULL)
782 take_input(last_cmd);
816 prregs(excp); /* print regs */
864 printf("Unrecognized command: ");
866 if (' ' < cmd && cmd <= '~')
869 printf("\\x%x", cmd);
871 } while (cmd != '\n');
872 printf(" (type ? for help)\n");
879 * Step a single instruction.
880 * Some instructions we emulate, others we execute with MSR_SE set.
882 static int do_step(struct pt_regs *regs)
887 /* check we are in 64-bit kernel mode, translation enabled */
888 if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
889 if (mread(regs->nip, &instr, 4) == 4) {
890 stepped = emulate_step(regs, instr);
892 printf("Couldn't single-step %s instruction\n",
893 (IS_RFID(instr)? "rfid": "mtmsrd"));
897 regs->trap = 0xd00 | (regs->trap & 1);
898 printf("stepped to ");
899 xmon_print_symbol(regs->nip, " ", "\n");
900 ppc_inst_dump(regs->nip, 1, 0);
909 static void bootcmds(void)
915 ppc_md.restart(NULL);
922 static int cpu_cmd(void)
929 if (!scanhex(&cpu)) {
930 /* print cpus waiting or in xmon */
931 printf("cpus stopped:");
933 for (cpu = 0; cpu < NR_CPUS; ++cpu) {
934 if (cpu_isset(cpu, cpus_in_xmon)) {
940 printf("-%x", cpu - 1);
945 printf("-%x", NR_CPUS - 1);
949 /* try to switch to cpu specified */
950 if (!cpu_isset(cpu, cpus_in_xmon)) {
951 printf("cpu 0x%x isn't in xmon\n", cpu);
958 while (!xmon_taken) {
959 if (--timeout == 0) {
960 if (test_and_set_bit(0, &xmon_taken))
962 /* take control back */
964 xmon_owner = smp_processor_id();
965 printf("cpu %u didn't take control\n", cpu);
973 #endif /* CONFIG_SMP */
976 static unsigned short fcstab[256] = {
977 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
978 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
979 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
980 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
981 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
982 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
983 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
984 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
985 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
986 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
987 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
988 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
989 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
990 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
991 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
992 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
993 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
994 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
995 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
996 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
997 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
998 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
999 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1000 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1001 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1002 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1003 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1004 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1005 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1006 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1007 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1008 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1011 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1020 if (!scanhex(&adrs))
1022 if (!scanhex(&ncsum))
1025 for (i = 0; i < ncsum; ++i) {
1026 if (mread(adrs+i, &v, 1) == 0) {
1027 printf("csum stopped at %x\n", adrs+i);
1032 printf("%x\n", fcs);
1036 * Check if this is a suitable place to put a breakpoint.
1038 static long check_bp_loc(unsigned long addr)
1043 if (addr < KERNELBASE) {
1044 printf("Breakpoints may only be placed at kernel addresses\n");
1047 if (!mread(addr, &instr, sizeof(instr))) {
1048 printf("Can't read instruction at address %lx\n", addr);
1051 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1052 printf("Breakpoints may not be placed on mtmsrd or rfid "
1059 static char *breakpoint_help_string =
1060 "Breakpoint command usage:\n"
1061 "b show breakpoints\n"
1062 "b <addr> [cnt] set breakpoint at given instr addr\n"
1063 "bc clear all breakpoints\n"
1064 "bc <n/addr> clear breakpoint number n or at addr\n"
1065 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1066 "bd <addr> [cnt] set hardware data breakpoint\n"
1076 const char badaddr[] = "Only kernel addresses are permitted "
1077 "for breakpoints\n";
1081 case 'd': /* bd - hardware data breakpoint */
1086 else if (cmd == 'w')
1092 if (scanhex(&dabr.address)) {
1093 if (dabr.address < KERNELBASE) {
1098 dabr.enabled = mode | BP_DABR;
1102 case 'i': /* bi - hardware instr breakpoint */
1103 if (!(cur_cpu_spec->cpu_features & CPU_FTR_IABR)) {
1104 printf("Hardware instruction breakpoint "
1105 "not supported on this cpu\n");
1109 iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1114 if (!check_bp_loc(a))
1116 bp = new_breakpoint(a);
1118 bp->enabled |= BP_IABR | BP_IABR_TE;
1125 /* clear all breakpoints */
1126 for (i = 0; i < NBPTS; ++i)
1127 bpts[i].enabled = 0;
1130 printf("All breakpoints cleared\n");
1134 if (a <= NBPTS && a >= 1) {
1135 /* assume a breakpoint number */
1136 bp = &bpts[a-1]; /* bp nums are 1 based */
1138 /* assume a breakpoint address */
1139 bp = at_breakpoint(a);
1141 printf("No breakpoint at %x\n", a);
1146 printf("Cleared breakpoint %x (", BP_NUM(bp));
1147 xmon_print_symbol(bp->address, " ", ")\n");
1155 printf(breakpoint_help_string);
1160 /* print all breakpoints */
1161 printf(" type address\n");
1163 printf(" data %.16lx [", dabr.address);
1164 if (dabr.enabled & 1)
1166 if (dabr.enabled & 2)
1170 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1173 printf("%2x %s ", BP_NUM(bp),
1174 (bp->enabled & BP_IABR)? "inst": "trap");
1175 xmon_print_symbol(bp->address, " ", "\n");
1180 if (!check_bp_loc(a))
1182 bp = new_breakpoint(a);
1184 bp->enabled |= BP_TRAP;
1189 /* Very cheap human name for vector lookup. */
1191 const char *getvecname(unsigned long vec)
1196 case 0x100: ret = "(System Reset)"; break;
1197 case 0x200: ret = "(Machine Check)"; break;
1198 case 0x300: ret = "(Data Access)"; break;
1199 case 0x380: ret = "(Data SLB Access)"; break;
1200 case 0x400: ret = "(Instruction Access)"; break;
1201 case 0x480: ret = "(Instruction SLB Access)"; break;
1202 case 0x500: ret = "(Hardware Interrupt)"; break;
1203 case 0x600: ret = "(Alignment)"; break;
1204 case 0x700: ret = "(Program Check)"; break;
1205 case 0x800: ret = "(FPU Unavailable)"; break;
1206 case 0x900: ret = "(Decrementer)"; break;
1207 case 0xc00: ret = "(System Call)"; break;
1208 case 0xd00: ret = "(Single Step)"; break;
1209 case 0xf00: ret = "(Performance Monitor)"; break;
1210 case 0xf20: ret = "(Altivec Unavailable)"; break;
1211 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1217 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1218 unsigned long *endp)
1220 unsigned long size, offset;
1224 *startp = *endp = 0;
1227 if (setjmp(bus_error_jmp) == 0) {
1228 catch_memory_errors = 1;
1230 name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr);
1232 *startp = pc - offset;
1233 *endp = pc - offset + size;
1237 catch_memory_errors = 0;
1240 static int xmon_depth_to_print = 64;
1242 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1246 unsigned long newsp;
1247 unsigned long marker;
1249 struct pt_regs regs;
1252 if (sp < PAGE_OFFSET) {
1254 printf("SP (%lx) is in userspace\n", sp);
1258 if (!mread(sp + 16, &ip, sizeof(unsigned long))
1259 || !mread(sp, &newsp, sizeof(unsigned long))) {
1260 printf("Couldn't read stack frame at %lx\n", sp);
1265 * For the first stack frame, try to work out if
1266 * LR and/or the saved LR value in the bottommost
1267 * stack frame are valid.
1269 if ((pc | lr) != 0) {
1270 unsigned long fnstart, fnend;
1271 unsigned long nextip;
1274 get_function_bounds(pc, &fnstart, &fnend);
1277 mread(newsp + 16, &nextip,
1278 sizeof(unsigned long));
1280 if (lr < PAGE_OFFSET
1281 || (fnstart <= lr && lr < fnend))
1283 } else if (lr == nextip) {
1285 } else if (lr >= PAGE_OFFSET
1286 && !(fnstart <= lr && lr < fnend)) {
1287 printf("[link register ] ");
1288 xmon_print_symbol(lr, " ", "\n");
1291 printf("[%.16lx] ", sp);
1292 xmon_print_symbol(ip, " ", " (unreliable)\n");
1297 printf("[%.16lx] ", sp);
1298 xmon_print_symbol(ip, " ", "\n");
1301 /* Look for "regshere" marker to see if this is
1302 an exception frame. */
1303 if (mread(sp + 0x60, &marker, sizeof(unsigned long))
1304 && marker == 0x7265677368657265ul) {
1305 if (mread(sp + 0x70, ®s, sizeof(regs))
1307 printf("Couldn't read registers at %lx\n",
1311 printf("--- Exception: %lx %s at ", regs.trap,
1312 getvecname(TRAP(®s)));
1315 xmon_print_symbol(pc, " ", "\n");
1322 } while (count++ < xmon_depth_to_print);
1325 static void backtrace(struct pt_regs *excp)
1330 xmon_show_stack(sp, 0, 0);
1332 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1336 static void print_bug_trap(struct pt_regs *regs)
1338 struct bug_entry *bug;
1341 if (regs->msr & MSR_PR)
1342 return; /* not in kernel */
1343 addr = regs->nip; /* address of trap instruction */
1344 if (addr < PAGE_OFFSET)
1346 bug = find_bug(regs->nip);
1349 if (bug->line & BUG_WARNING_TRAP)
1352 printf("kernel BUG in %s at %s:%d!\n",
1353 bug->function, bug->file, (unsigned int)bug->line);
1356 void excprint(struct pt_regs *fp)
1361 printf("cpu 0x%x: ", smp_processor_id());
1362 #endif /* CONFIG_SMP */
1365 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1367 xmon_print_symbol(fp->nip, ": ", "\n");
1369 printf(" lr: ", fp->link);
1370 xmon_print_symbol(fp->link, ": ", "\n");
1372 printf(" sp: %lx\n", fp->gpr[1]);
1373 printf(" msr: %lx\n", fp->msr);
1375 if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1376 printf(" dar: %lx\n", fp->dar);
1378 printf(" dsisr: %lx\n", fp->dsisr);
1381 printf(" current = 0x%lx\n", current);
1382 printf(" paca = 0x%lx\n", get_paca());
1384 printf(" pid = %ld, comm = %s\n",
1385 current->pid, current->comm);
1392 void prregs(struct pt_regs *fp)
1396 struct pt_regs regs;
1398 if (scanhex(&base)) {
1399 if (setjmp(bus_error_jmp) == 0) {
1400 catch_memory_errors = 1;
1402 regs = *(struct pt_regs *)base;
1406 catch_memory_errors = 0;
1407 printf("*** Error reading registers from %.16lx\n",
1411 catch_memory_errors = 0;
1415 if (FULL_REGS(fp)) {
1416 for (n = 0; n < 16; ++n)
1417 printf("R%.2ld = %.16lx R%.2ld = %.16lx\n",
1418 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1420 for (n = 0; n < 7; ++n)
1421 printf("R%.2ld = %.16lx R%.2ld = %.16lx\n",
1422 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1425 xmon_print_symbol(fp->nip, " ", "\n");
1427 xmon_print_symbol(fp->link, " ", "\n");
1428 printf("msr = %.16lx cr = %.8lx\n", fp->msr, fp->ccr);
1429 printf("ctr = %.16lx xer = %.16lx trap = %8lx\n",
1430 fp->ctr, fp->xer, fp->trap);
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;
1535 #ifdef CONFIG_PPC_ISERIES
1536 struct paca_struct *ptrPaca = NULL;
1537 struct lppaca *ptrLpPaca = NULL;
1538 struct ItLpRegSave *ptrLpRegSave = NULL;
1543 unsigned long sp, toc;
1544 asm("mr %0,1" : "=r" (sp) :);
1545 asm("mr %0,2" : "=r" (toc) :);
1547 printf("msr = %.16lx sprg0= %.16lx\n", get_msr(), get_sprg0());
1548 printf("pvr = %.16lx sprg1= %.16lx\n", get_pvr(), get_sprg1());
1549 printf("dec = %.16lx sprg2= %.16lx\n", get_dec(), get_sprg2());
1550 printf("sp = %.16lx sprg3= %.16lx\n", sp, get_sprg3());
1551 printf("toc = %.16lx dar = %.16lx\n", toc, get_dar());
1552 printf("srr0 = %.16lx srr1 = %.16lx\n", get_srr0(), get_srr1());
1553 #ifdef CONFIG_PPC_ISERIES
1554 // Dump out relevant Paca data areas.
1556 ptrPaca = get_paca();
1558 printf(" Local Processor Control Area (LpPaca): \n");
1559 ptrLpPaca = ptrPaca->lppaca_ptr;
1560 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1561 ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
1562 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1563 ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
1564 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
1566 printf(" Local Processor Register Save Area (LpRegSave): \n");
1567 ptrLpRegSave = ptrPaca->reg_save_ptr;
1568 printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n",
1569 ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
1570 printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n",
1571 ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
1572 printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n",
1573 ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
1582 val = read_spr(regno);
1584 write_spr(regno, val);
1587 printf("spr %lx = %lx\n", regno, read_spr(regno));
1599 * Stuff for reading and writing memory safely
1602 mread(unsigned long adrs, void *buf, int size)
1608 if (setjmp(bus_error_jmp) == 0) {
1609 catch_memory_errors = 1;
1615 *(short *)q = *(short *)p;
1618 *(int *)q = *(int *)p;
1621 *(long *)q = *(long *)p;
1624 for( ; n < size; ++n) {
1630 /* wait a little while to see if we get a machine check */
1634 catch_memory_errors = 0;
1639 mwrite(unsigned long adrs, void *buf, int size)
1645 if (setjmp(bus_error_jmp) == 0) {
1646 catch_memory_errors = 1;
1652 *(short *)p = *(short *)q;
1655 *(int *)p = *(int *)q;
1658 *(long *)p = *(long *)q;
1661 for ( ; n < size; ++n) {
1667 /* wait a little while to see if we get a machine check */
1671 printf("*** Error writing address %x\n", adrs + n);
1673 catch_memory_errors = 0;
1677 static int fault_type;
1678 static char *fault_chars[] = { "--", "**", "##" };
1681 handle_fault(struct pt_regs *regs)
1683 switch (TRAP(regs)) {
1695 longjmp(bus_error_jmp, 1);
1700 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1703 byterev(unsigned char *val, int size)
1709 SWAP(val[0], val[1], t);
1712 SWAP(val[0], val[3], t);
1713 SWAP(val[1], val[2], t);
1715 case 8: /* is there really any use for this? */
1716 SWAP(val[0], val[7], t);
1717 SWAP(val[1], val[6], t);
1718 SWAP(val[2], val[5], t);
1719 SWAP(val[3], val[4], t);
1727 static char *memex_help_string =
1728 "Memory examine command usage:\n"
1729 "m [addr] [flags] examine/change memory\n"
1730 " addr is optional. will start where left off.\n"
1731 " flags may include chars from this set:\n"
1732 " b modify by bytes (default)\n"
1733 " w modify by words (2 byte)\n"
1734 " l modify by longs (4 byte)\n"
1735 " d modify by doubleword (8 byte)\n"
1736 " r toggle reverse byte order mode\n"
1737 " n do not read memory (for i/o spaces)\n"
1738 " . ok to read (default)\n"
1739 "NOTE: flags are saved as defaults\n"
1742 static char *memex_subcmd_help_string =
1743 "Memory examine subcommands:\n"
1744 " hexval write this val to current location\n"
1745 " 'string' write chars from string to this location\n"
1746 " ' increment address\n"
1747 " ^ decrement address\n"
1748 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1749 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1750 " ` clear no-read flag\n"
1751 " ; stay at this addr\n"
1752 " v change to byte mode\n"
1753 " w change to word (2 byte) mode\n"
1754 " l change to long (4 byte) mode\n"
1755 " u change to doubleword (8 byte) mode\n"
1756 " m addr change current addr\n"
1757 " n toggle no-read flag\n"
1758 " r toggle byte reverse flag\n"
1759 " < count back up count bytes\n"
1760 " > count skip forward count bytes\n"
1761 " x exit this mode\n"
1767 int cmd, inc, i, nslash;
1769 unsigned char val[16];
1771 scanhex((void *)&adrs);
1774 printf(memex_help_string);
1780 while ((cmd = skipbl()) != '\n') {
1782 case 'b': size = 1; break;
1783 case 'w': size = 2; break;
1784 case 'l': size = 4; break;
1785 case 'd': size = 8; break;
1786 case 'r': brev = !brev; break;
1787 case 'n': mnoread = 1; break;
1788 case '.': mnoread = 0; break;
1797 n = mread(adrs, val, size);
1798 printf("%.16x%c", adrs, brev? 'r': ' ');
1803 for (i = 0; i < n; ++i)
1804 printf("%.2x", val[i]);
1805 for (; i < size; ++i)
1806 printf("%s", fault_chars[fault_type]);
1813 for (i = 0; i < size; ++i)
1814 val[i] = n >> (i * 8);
1817 mwrite(adrs, val, size);
1830 else if( n == '\'' )
1832 for (i = 0; i < size; ++i)
1833 val[i] = n >> (i * 8);
1836 mwrite(adrs, val, size);
1873 adrs -= 1 << nslash;
1877 adrs += 1 << nslash;
1881 adrs += 1 << -nslash;
1885 adrs -= 1 << -nslash;
1888 scanhex((void *)&adrs);
1907 printf(memex_subcmd_help_string);
1922 case 'n': c = '\n'; break;
1923 case 'r': c = '\r'; break;
1924 case 'b': c = '\b'; break;
1925 case 't': c = '\t'; break;
1930 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
1931 || ('a' <= (c) && (c) <= 'f') \
1932 || ('A' <= (c) && (c) <= 'F'))
1939 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
1941 scanhex((void *)&adrs);
1948 else if (nidump > MAX_DUMP)
1950 adrs += ppc_inst_dump(adrs, nidump, 1);
1956 else if (ndump > MAX_DUMP)
1958 prdump(adrs, ndump);
1965 prdump(unsigned long adrs, long ndump)
1967 long n, m, c, r, nr;
1968 unsigned char temp[16];
1970 for (n = ndump; n > 0;) {
1971 printf("%.16lx", adrs);
1974 nr = mread(adrs, temp, r);
1976 for (m = 0; m < r; ++m) {
1977 if ((m & 7) == 0 && m > 0)
1980 printf("%.2x", temp[m]);
1982 printf("%s", fault_chars[fault_type]);
1989 for (m = 0; m < r; ++m) {
1992 putchar(' ' <= c && c <= '~'? c: '.');
2006 ppc_inst_dump(unsigned long adr, long count, int praddr)
2009 unsigned long first_adr;
2010 unsigned long inst, last_inst = 0;
2011 unsigned char val[4];
2014 for (first_adr = adr; count > 0; --count, adr += 4) {
2015 nr = mread(adr, val, 4);
2018 const char *x = fault_chars[fault_type];
2019 printf("%.16lx %s%s%s%s\n", adr, x, x, x, x);
2023 inst = GETWORD(val);
2024 if (adr > first_adr && inst == last_inst) {
2034 printf("%.16lx %.8x", adr, inst);
2036 print_insn_powerpc(inst, adr, 0); /* always returns 4 */
2039 return adr - first_adr;
2043 print_address(unsigned long addr)
2045 xmon_print_symbol(addr, "\t# ", "");
2050 * Memory operations - move, set, print differences
2052 static unsigned long mdest; /* destination address */
2053 static unsigned long msrc; /* source address */
2054 static unsigned long mval; /* byte value to set memory to */
2055 static unsigned long mcount; /* # bytes to affect */
2056 static unsigned long mdiffs; /* max # differences to print */
2061 scanhex((void *)&mdest);
2062 if( termch != '\n' )
2064 scanhex((void *)(cmd == 's'? &mval: &msrc));
2065 if( termch != '\n' )
2067 scanhex((void *)&mcount);
2070 memmove((void *)mdest, (void *)msrc, mcount);
2073 memset((void *)mdest, mval, mcount);
2076 if( termch != '\n' )
2078 scanhex((void *)&mdiffs);
2079 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2085 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2090 for( n = nb; n > 0; --n )
2091 if( *p1++ != *p2++ )
2092 if( ++prt <= maxpr )
2093 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2094 p1[-1], p2 - 1, p2[-1]);
2096 printf("Total of %d differences\n", prt);
2099 static unsigned mend;
2100 static unsigned mask;
2106 unsigned char val[4];
2109 scanhex((void *)&mdest);
2110 if (termch != '\n') {
2112 scanhex((void *)&mend);
2113 if (termch != '\n') {
2115 scanhex((void *)&mval);
2117 if (termch != '\n') termch = 0;
2118 scanhex((void *)&mask);
2122 for (a = mdest; a < mend; a += 4) {
2123 if (mread(a, val, 4) == 4
2124 && ((GETWORD(val) ^ mval) & mask) == 0) {
2125 printf("%.16x: %.16x\n", a, GETWORD(val));
2132 static unsigned long mskip = 0x1000;
2133 static unsigned long mlim = 0xffffffff;
2143 if (termch != '\n') termch = 0;
2145 if (termch != '\n') termch = 0;
2148 for (a = mdest; a < mlim; a += mskip) {
2149 ok = mread(a, &v, 1);
2151 printf("%.8x .. ", a);
2153 } else if (!ok && ook)
2154 printf("%.8x\n", a - mskip);
2160 printf("%.8x\n", a - mskip);
2163 /* Input scanning routines */
2174 while( c == ' ' || c == '\t' )
2180 static char *regnames[N_PTREGS] = {
2181 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2182 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2183 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2184 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2185 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", "softe",
2186 "trap", "dar", "dsisr", "res"
2190 scanhex(unsigned long *vp)
2197 /* parse register name */
2201 for (i = 0; i < sizeof(regname) - 1; ++i) {
2210 for (i = 0; i < N_PTREGS; ++i) {
2211 if (strcmp(regnames[i], regname) == 0) {
2212 if (xmon_regs == NULL) {
2213 printf("regs not available\n");
2216 *vp = ((unsigned long *)xmon_regs)[i];
2220 printf("invalid register name '%%%s'\n", regname);
2224 /* skip leading "0x" if any */
2238 } else if (c == '$') {
2240 for (i=0; i<63; i++) {
2249 *vp = kallsyms_lookup_name(tmpstr);
2251 printf("unknown symbol '%s'\n", tmpstr);
2287 if( '0' <= c && c <= '9' )
2289 if( 'A' <= c && c <= 'F' )
2290 return c - ('A' - 10);
2291 if( 'a' <= c && c <= 'f' )
2292 return c - ('a' - 10);
2297 getstring(char *s, int size)
2308 } while( c != ' ' && c != '\t' && c != '\n' );
2313 static char line[256];
2314 static char *lineptr;
2325 if (lineptr == NULL || *lineptr == 0) {
2326 if (fgets(line, sizeof(line), stdin) == NULL) {
2336 take_input(char *str)
2345 int type = inchar();
2347 static char tmp[64];
2352 xmon_print_symbol(addr, ": ", "\n");
2357 if (setjmp(bus_error_jmp) == 0) {
2358 catch_memory_errors = 1;
2360 addr = kallsyms_lookup_name(tmp);
2362 printf("%s: %lx\n", tmp, addr);
2364 printf("Symbol '%s' not found.\n", tmp);
2367 catch_memory_errors = 0;
2374 /* Print an address in numeric and symbolic form (if possible) */
2375 static void xmon_print_symbol(unsigned long address, const char *mid,
2379 const char *name = NULL;
2380 unsigned long offset, size;
2382 printf("%.16lx", address);
2383 if (setjmp(bus_error_jmp) == 0) {
2384 catch_memory_errors = 1;
2386 name = kallsyms_lookup(address, &size, &offset, &modname,
2389 /* wait a little while to see if we get a machine check */
2393 catch_memory_errors = 0;
2396 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2398 printf(" [%s]", modname);
2400 printf("%s", after);
2403 static void debug_trace(void)
2405 unsigned long val, cmd, on;
2409 /* show current state */
2411 printf("ppc64_debug_switch = 0x%lx\n", ppc64_debug_switch);
2412 for (i = 0; i < PPCDBG_NUM_FLAGS ;i++) {
2413 on = PPCDBG_BITVAL(i) & ppc64_debug_switch;
2414 printf("%02x %s %12s ", i, on ? "on " : "off", trace_names[i] ? trace_names[i] : "");
2415 if (((i+1) % 3) == 0)
2421 while (cmd != '\n') {
2422 on = 1; /* default if no sign given */
2423 while (cmd == '+' || cmd == '-') {
2426 if (cmd == ' ' || cmd == '\n') { /* Turn on or off based on + or - */
2427 ppc64_debug_switch = on ? PPCDBG_ALL:PPCDBG_NONE;
2428 printf("Setting all values to %s...\n", on ? "on" : "off");
2429 if (cmd == '\n') return;
2430 else cmd = skipbl();
2435 termch = cmd; /* not +/- ... let scanhex see it */
2436 scanhex((void *)&val);
2438 printf("Value %x out of range:\n", val);
2442 ppc64_debug_switch |= PPCDBG_BITVAL(val);
2443 printf("enable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
2445 ppc64_debug_switch &= ~PPCDBG_BITVAL(val);
2446 printf("disable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
2452 static void dump_slb(void)
2457 printf("SLB contents of cpu %x\n", smp_processor_id());
2459 for (i = 0; i < SLB_NUM_ENTRIES; i++) {
2460 asm volatile("slbmfee %0,%1" : "=r" (tmp) : "r" (i));
2461 printf("%02d %016lx ", i, tmp);
2463 asm volatile("slbmfev %0,%1" : "=r" (tmp) : "r" (i));
2464 printf("%016lx\n", tmp);
2468 static void dump_stab(void)
2471 unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2473 printf("Segment table contents of cpu %x\n", smp_processor_id());
2475 for (i = 0; i < PAGE_SIZE/16; i++) {
2482 printf("%03d %016lx ", i, a);
2483 printf("%016lx\n", b);
2488 void xmon_init(void)
2491 __debugger_ipi = xmon_ipi;
2492 __debugger_bpt = xmon_bpt;
2493 __debugger_sstep = xmon_sstep;
2494 __debugger_iabr_match = xmon_iabr_match;
2495 __debugger_dabr_match = xmon_dabr_match;
2496 __debugger_fault_handler = xmon_fault_handler;
2499 void dump_segments(void)
2501 if (cur_cpu_spec->cpu_features & CPU_FTR_SLB)