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);
628 static struct bpt *at_breakpoint(unsigned long pc)
634 for (i = 0; i < NBPTS; ++i, ++bp)
635 if (bp->enabled && pc == bp->address)
640 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
644 off = nip - (unsigned long) bpts;
645 if (off >= sizeof(bpts))
647 off %= sizeof(struct bpt);
648 if (off != offsetof(struct bpt, instr[0])
649 && off != offsetof(struct bpt, instr[1]))
651 *offp = off - offsetof(struct bpt, instr[0]);
652 return (struct bpt *) (nip - off);
655 static struct bpt *new_breakpoint(unsigned long a)
660 bp = at_breakpoint(a);
664 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
665 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
667 bp->instr[1] = bpinstr;
668 store_inst(&bp->instr[1]);
673 printf("Sorry, no free breakpoints. Please clear one first.\n");
677 static void insert_bpts(void)
683 for (i = 0; i < NBPTS; ++i, ++bp) {
684 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
686 if (mread(bp->address, &bp->instr[0], 4) != 4) {
687 printf("Couldn't read instruction at %lx, "
688 "disabling breakpoint there\n", bp->address);
692 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
693 printf("Breakpoint at %lx is on an mtmsrd or rfid "
694 "instruction, disabling it\n", bp->address);
698 store_inst(&bp->instr[0]);
699 if (bp->enabled & BP_IABR)
701 if (mwrite(bp->address, &bpinstr, 4) != 4) {
702 printf("Couldn't write instruction at %lx, "
703 "disabling breakpoint there\n", bp->address);
704 bp->enabled &= ~BP_TRAP;
707 store_inst((void *)bp->address);
711 static void insert_cpu_bpts(void)
714 set_dabr(dabr.address | (dabr.enabled & 7));
715 if (iabr && (cur_cpu_spec->cpu_features & CPU_FTR_IABR))
716 set_iabr(iabr->address
717 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
720 static void remove_bpts(void)
727 for (i = 0; i < NBPTS; ++i, ++bp) {
728 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
730 if (mread(bp->address, &instr, 4) == 4
732 && mwrite(bp->address, &bp->instr, 4) != 4)
733 printf("Couldn't remove breakpoint at %lx\n",
736 store_inst((void *)bp->address);
740 static void remove_cpu_bpts(void)
743 if ((cur_cpu_spec->cpu_features & CPU_FTR_IABR))
747 /* Command interpreting routine */
748 static char *last_cmd;
751 cmds(struct pt_regs *excp)
759 printf("%x:", smp_processor_id());
760 #endif /* CONFIG_SMP */
767 if (last_cmd == NULL)
769 take_input(last_cmd);
803 prregs(excp); /* print regs */
851 printf("Unrecognized command: ");
853 if (' ' < cmd && cmd <= '~')
856 printf("\\x%x", cmd);
858 } while (cmd != '\n');
859 printf(" (type ? for help)\n");
866 * Step a single instruction.
867 * Some instructions we emulate, others we execute with MSR_SE set.
869 static int do_step(struct pt_regs *regs)
874 /* check we are in 64-bit kernel mode, translation enabled */
875 if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
876 if (mread(regs->nip, &instr, 4) == 4) {
877 stepped = emulate_step(regs, instr);
879 printf("Couldn't single-step %s instruction\n",
880 (IS_RFID(instr)? "rfid": "mtmsrd"));
884 regs->trap = 0xd00 | (regs->trap & 1);
885 printf("stepped to ");
886 xmon_print_symbol(regs->nip, " ", "\n");
887 ppc_inst_dump(regs->nip, 1, 0);
896 static void bootcmds(void)
902 ppc_md.restart(NULL);
909 static int cpu_cmd(void)
916 if (!scanhex(&cpu)) {
917 /* print cpus waiting or in xmon */
918 printf("cpus stopped:");
920 for (cpu = 0; cpu < NR_CPUS; ++cpu) {
921 if (cpu_isset(cpu, cpus_in_xmon)) {
927 printf("-%x", cpu - 1);
932 printf("-%x", NR_CPUS - 1);
936 /* try to switch to cpu specified */
937 if (!cpu_isset(cpu, cpus_in_xmon)) {
938 printf("cpu 0x%x isn't in xmon\n", cpu);
945 while (!xmon_taken) {
946 if (--timeout == 0) {
947 if (test_and_set_bit(0, &xmon_taken))
949 /* take control back */
951 xmon_owner = smp_processor_id();
952 printf("cpu %u didn't take control\n", cpu);
960 #endif /* CONFIG_SMP */
963 static unsigned short fcstab[256] = {
964 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
965 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
966 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
967 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
968 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
969 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
970 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
971 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
972 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
973 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
974 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
975 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
976 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
977 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
978 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
979 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
980 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
981 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
982 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
983 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
984 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
985 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
986 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
987 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
988 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
989 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
990 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
991 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
992 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
993 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
994 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
995 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
998 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1007 if (!scanhex(&adrs))
1009 if (!scanhex(&ncsum))
1012 for (i = 0; i < ncsum; ++i) {
1013 if (mread(adrs+i, &v, 1) == 0) {
1014 printf("csum stopped at %x\n", adrs+i);
1019 printf("%x\n", fcs);
1023 * Check if this is a suitable place to put a breakpoint.
1025 static long check_bp_loc(unsigned long addr)
1030 if (addr < KERNELBASE) {
1031 printf("Breakpoints may only be placed at kernel addresses\n");
1034 if (!mread(addr, &instr, sizeof(instr))) {
1035 printf("Can't read instruction at address %lx\n", addr);
1038 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1039 printf("Breakpoints may not be placed on mtmsrd or rfid "
1046 static char *breakpoint_help_string =
1047 "Breakpoint command usage:\n"
1048 "b show breakpoints\n"
1049 "b <addr> [cnt] set breakpoint at given instr addr\n"
1050 "bc clear all breakpoints\n"
1051 "bc <n/addr> clear breakpoint number n or at addr\n"
1052 "bi <addr> [cnt] set hardware instr breakpoint (broken?)\n"
1053 "bd <addr> [cnt] set hardware data breakpoint (broken?)\n"
1063 const char badaddr[] = "Only kernel addresses are permitted "
1064 "for breakpoints\n";
1068 case 'd': /* bd - hardware data breakpoint */
1073 else if (cmd == 'w')
1079 if (scanhex(&dabr.address)) {
1080 if (dabr.address < KERNELBASE) {
1085 dabr.enabled = mode | BP_DABR;
1089 case 'i': /* bi - hardware instr breakpoint */
1090 if (!(cur_cpu_spec->cpu_features & CPU_FTR_IABR)) {
1091 printf("Hardware instruction breakpoint "
1092 "not supported on this cpu\n");
1096 iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1101 if (!check_bp_loc(a))
1103 bp = new_breakpoint(a);
1105 bp->enabled |= BP_IABR | BP_IABR_TE;
1112 /* clear all breakpoints */
1113 for (i = 0; i < NBPTS; ++i)
1114 bpts[i].enabled = 0;
1117 printf("All breakpoints cleared\n");
1121 if (a <= NBPTS && a >= 1) {
1122 /* assume a breakpoint number */
1123 bp = &bpts[a-1]; /* bp nums are 1 based */
1125 /* assume a breakpoint address */
1126 bp = at_breakpoint(a);
1128 printf("No breakpoint at %x\n", a);
1133 printf("Cleared breakpoint %x (", BP_NUM(bp));
1134 xmon_print_symbol(bp->address, " ", ")\n");
1142 printf(breakpoint_help_string);
1147 /* print all breakpoints */
1148 printf(" type address\n");
1150 printf(" data %.16lx [", dabr.address);
1151 if (dabr.enabled & 1)
1153 if (dabr.enabled & 2)
1157 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1160 printf("%2x %s ", BP_NUM(bp),
1161 (bp->enabled & BP_IABR)? "inst": "trap");
1162 xmon_print_symbol(bp->address, " ", "\n");
1167 if (!check_bp_loc(a))
1169 bp = new_breakpoint(a);
1171 bp->enabled |= BP_TRAP;
1176 /* Very cheap human name for vector lookup. */
1178 const char *getvecname(unsigned long vec)
1183 case 0x100: ret = "(System Reset)"; break;
1184 case 0x200: ret = "(Machine Check)"; break;
1185 case 0x300: ret = "(Data Access)"; break;
1186 case 0x380: ret = "(Data SLB Access)"; break;
1187 case 0x400: ret = "(Instruction Access)"; break;
1188 case 0x480: ret = "(Instruction SLB Access)"; break;
1189 case 0x500: ret = "(Hardware Interrupt)"; break;
1190 case 0x600: ret = "(Alignment)"; break;
1191 case 0x700: ret = "(Program Check)"; break;
1192 case 0x800: ret = "(FPU Unavailable)"; break;
1193 case 0x900: ret = "(Decrementer)"; break;
1194 case 0xc00: ret = "(System Call)"; break;
1195 case 0xd00: ret = "(Single Step)"; break;
1196 case 0xf00: ret = "(Performance Monitor)"; break;
1197 case 0xf20: ret = "(Altivec Unavailable)"; break;
1198 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1204 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1205 unsigned long *endp)
1207 unsigned long size, offset;
1211 *startp = *endp = 0;
1214 if (setjmp(bus_error_jmp) == 0) {
1215 catch_memory_errors = 1;
1217 name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr);
1219 *startp = pc - offset;
1220 *endp = pc - offset + size;
1224 catch_memory_errors = 0;
1227 static int xmon_depth_to_print = 64;
1229 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1233 unsigned long newsp;
1234 unsigned long marker;
1236 struct pt_regs regs;
1239 if (sp < PAGE_OFFSET) {
1241 printf("SP (%lx) is in userspace\n", sp);
1245 if (!mread(sp + 16, &ip, sizeof(unsigned long))
1246 || !mread(sp, &newsp, sizeof(unsigned long))) {
1247 printf("Couldn't read stack frame at %lx\n", sp);
1252 * For the first stack frame, try to work out if
1253 * LR and/or the saved LR value in the bottommost
1254 * stack frame are valid.
1256 if ((pc | lr) != 0) {
1257 unsigned long fnstart, fnend;
1258 unsigned long nextip;
1261 get_function_bounds(pc, &fnstart, &fnend);
1264 mread(newsp + 16, &nextip,
1265 sizeof(unsigned long));
1267 if (lr < PAGE_OFFSET
1268 || (fnstart <= lr && lr < fnend))
1270 } else if (lr == nextip) {
1272 } else if (lr >= PAGE_OFFSET
1273 && !(fnstart <= lr && lr < fnend)) {
1274 printf("[link register ] ");
1275 xmon_print_symbol(lr, " ", "\n");
1278 printf("[%.16lx] ", sp);
1279 xmon_print_symbol(ip, " ", " (unreliable)\n");
1284 printf("[%.16lx] ", sp);
1285 xmon_print_symbol(ip, " ", "\n");
1288 /* Look for "regshere" marker to see if this is
1289 an exception frame. */
1290 if (mread(sp + 0x60, &marker, sizeof(unsigned long))
1291 && marker == 0x7265677368657265ul) {
1292 if (mread(sp + 0x70, ®s, sizeof(regs))
1294 printf("Couldn't read registers at %lx\n",
1298 printf("--- Exception: %lx %s at ", regs.trap,
1299 getvecname(TRAP(®s)));
1302 xmon_print_symbol(pc, " ", "\n");
1309 } while (count++ < xmon_depth_to_print);
1312 static void backtrace(struct pt_regs *excp)
1317 xmon_show_stack(sp, 0, 0);
1319 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1323 static void print_bug_trap(struct pt_regs *regs)
1325 struct bug_entry *bug;
1328 if (regs->msr & MSR_PR)
1329 return; /* not in kernel */
1330 addr = regs->nip; /* address of trap instruction */
1331 if (addr < PAGE_OFFSET)
1333 bug = find_bug(regs->nip);
1336 if (bug->line & BUG_WARNING_TRAP)
1339 printf("kernel BUG in %s at %s:%d!\n",
1340 bug->function, bug->file, (unsigned int)bug->line);
1343 void excprint(struct pt_regs *fp)
1348 printf("cpu 0x%x: ", smp_processor_id());
1349 #endif /* CONFIG_SMP */
1352 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1354 xmon_print_symbol(fp->nip, ": ", "\n");
1356 printf(" lr: ", fp->link);
1357 xmon_print_symbol(fp->link, ": ", "\n");
1359 printf(" sp: %lx\n", fp->gpr[1]);
1360 printf(" msr: %lx\n", fp->msr);
1362 if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1363 printf(" dar: %lx\n", fp->dar);
1365 printf(" dsisr: %lx\n", fp->dsisr);
1368 printf(" current = 0x%lx\n", current);
1369 printf(" paca = 0x%lx\n", get_paca());
1371 printf(" pid = %ld, comm = %s\n",
1372 current->pid, current->comm);
1379 void prregs(struct pt_regs *fp)
1383 struct pt_regs regs;
1385 if (scanhex(&base)) {
1386 if (setjmp(bus_error_jmp) == 0) {
1387 catch_memory_errors = 1;
1389 regs = *(struct pt_regs *)base;
1393 catch_memory_errors = 0;
1394 printf("*** Error reading registers from %.16lx\n",
1398 catch_memory_errors = 0;
1402 if (FULL_REGS(fp)) {
1403 for (n = 0; n < 16; ++n)
1404 printf("R%.2ld = %.16lx R%.2ld = %.16lx\n",
1405 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1407 for (n = 0; n < 7; ++n)
1408 printf("R%.2ld = %.16lx R%.2ld = %.16lx\n",
1409 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1412 xmon_print_symbol(fp->nip, " ", "\n");
1414 xmon_print_symbol(fp->link, " ", "\n");
1415 printf("msr = %.16lx cr = %.8lx\n", fp->msr, fp->ccr);
1416 printf("ctr = %.16lx xer = %.16lx trap = %8lx\n",
1417 fp->ctr, fp->xer, fp->trap);
1420 void cacheflush(void)
1423 unsigned long nflush;
1428 scanhex((void *)&adrs);
1433 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1434 if (setjmp(bus_error_jmp) == 0) {
1435 catch_memory_errors = 1;
1439 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1440 cflush((void *) adrs);
1442 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1443 cinval((void *) adrs);
1446 /* wait a little while to see if we get a machine check */
1449 catch_memory_errors = 0;
1455 unsigned int instrs[2];
1456 unsigned long (*code)(void);
1457 unsigned long opd[3];
1458 unsigned long ret = -1UL;
1460 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1461 instrs[1] = 0x4e800020;
1462 opd[0] = (unsigned long)instrs;
1466 store_inst(instrs+1);
1467 code = (unsigned long (*)(void)) opd;
1469 if (setjmp(bus_error_jmp) == 0) {
1470 catch_memory_errors = 1;
1476 /* wait a little while to see if we get a machine check */
1485 write_spr(int n, unsigned long val)
1487 unsigned int instrs[2];
1488 unsigned long (*code)(unsigned long);
1489 unsigned long opd[3];
1491 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1492 instrs[1] = 0x4e800020;
1493 opd[0] = (unsigned long)instrs;
1497 store_inst(instrs+1);
1498 code = (unsigned long (*)(unsigned long)) opd;
1500 if (setjmp(bus_error_jmp) == 0) {
1501 catch_memory_errors = 1;
1507 /* wait a little while to see if we get a machine check */
1513 static unsigned long regno;
1514 extern char exc_prolog;
1515 extern char dec_exc;
1522 #ifdef CONFIG_PPC_ISERIES
1523 struct paca_struct *ptrPaca = NULL;
1524 struct lppaca *ptrLpPaca = NULL;
1525 struct ItLpRegSave *ptrLpRegSave = NULL;
1530 unsigned long sp, toc;
1531 asm("mr %0,1" : "=r" (sp) :);
1532 asm("mr %0,2" : "=r" (toc) :);
1534 printf("msr = %.16lx sprg0= %.16lx\n", get_msr(), get_sprg0());
1535 printf("pvr = %.16lx sprg1= %.16lx\n", get_pvr(), get_sprg1());
1536 printf("dec = %.16lx sprg2= %.16lx\n", get_dec(), get_sprg2());
1537 printf("sp = %.16lx sprg3= %.16lx\n", sp, get_sprg3());
1538 printf("toc = %.16lx dar = %.16lx\n", toc, get_dar());
1539 printf("srr0 = %.16lx srr1 = %.16lx\n", get_srr0(), get_srr1());
1540 #ifdef CONFIG_PPC_ISERIES
1541 // Dump out relevant Paca data areas.
1543 ptrPaca = get_paca();
1545 printf(" Local Processor Control Area (LpPaca): \n");
1546 ptrLpPaca = ptrPaca->lppaca_ptr;
1547 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1548 ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
1549 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1550 ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
1551 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
1553 printf(" Local Processor Register Save Area (LpRegSave): \n");
1554 ptrLpRegSave = ptrPaca->reg_save_ptr;
1555 printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n",
1556 ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
1557 printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n",
1558 ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
1559 printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n",
1560 ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
1569 val = read_spr(regno);
1571 write_spr(regno, val);
1574 printf("spr %lx = %lx\n", regno, read_spr(regno));
1586 * Stuff for reading and writing memory safely
1589 mread(unsigned long adrs, void *buf, int size)
1595 if (setjmp(bus_error_jmp) == 0) {
1596 catch_memory_errors = 1;
1602 *(short *)q = *(short *)p;
1605 *(int *)q = *(int *)p;
1608 *(long *)q = *(long *)p;
1611 for( ; n < size; ++n) {
1617 /* wait a little while to see if we get a machine check */
1621 catch_memory_errors = 0;
1626 mwrite(unsigned long adrs, void *buf, int size)
1632 if (setjmp(bus_error_jmp) == 0) {
1633 catch_memory_errors = 1;
1639 *(short *)p = *(short *)q;
1642 *(int *)p = *(int *)q;
1645 *(long *)p = *(long *)q;
1648 for ( ; n < size; ++n) {
1654 /* wait a little while to see if we get a machine check */
1658 printf("*** Error writing address %x\n", adrs + n);
1660 catch_memory_errors = 0;
1664 static int fault_type;
1665 static char *fault_chars[] = { "--", "**", "##" };
1668 handle_fault(struct pt_regs *regs)
1670 switch (TRAP(regs)) {
1682 longjmp(bus_error_jmp, 1);
1687 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1690 byterev(unsigned char *val, int size)
1696 SWAP(val[0], val[1], t);
1699 SWAP(val[0], val[3], t);
1700 SWAP(val[1], val[2], t);
1702 case 8: /* is there really any use for this? */
1703 SWAP(val[0], val[7], t);
1704 SWAP(val[1], val[6], t);
1705 SWAP(val[2], val[5], t);
1706 SWAP(val[3], val[4], t);
1714 static char *memex_help_string =
1715 "Memory examine command usage:\n"
1716 "m [addr] [flags] examine/change memory\n"
1717 " addr is optional. will start where left off.\n"
1718 " flags may include chars from this set:\n"
1719 " b modify by bytes (default)\n"
1720 " w modify by words (2 byte)\n"
1721 " l modify by longs (4 byte)\n"
1722 " d modify by doubleword (8 byte)\n"
1723 " r toggle reverse byte order mode\n"
1724 " n do not read memory (for i/o spaces)\n"
1725 " . ok to read (default)\n"
1726 "NOTE: flags are saved as defaults\n"
1729 static char *memex_subcmd_help_string =
1730 "Memory examine subcommands:\n"
1731 " hexval write this val to current location\n"
1732 " 'string' write chars from string to this location\n"
1733 " ' increment address\n"
1734 " ^ decrement address\n"
1735 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1736 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1737 " ` clear no-read flag\n"
1738 " ; stay at this addr\n"
1739 " v change to byte mode\n"
1740 " w change to word (2 byte) mode\n"
1741 " l change to long (4 byte) mode\n"
1742 " u change to doubleword (8 byte) mode\n"
1743 " m addr change current addr\n"
1744 " n toggle no-read flag\n"
1745 " r toggle byte reverse flag\n"
1746 " < count back up count bytes\n"
1747 " > count skip forward count bytes\n"
1748 " x exit this mode\n"
1754 int cmd, inc, i, nslash;
1756 unsigned char val[16];
1758 scanhex((void *)&adrs);
1761 printf(memex_help_string);
1767 while ((cmd = skipbl()) != '\n') {
1769 case 'b': size = 1; break;
1770 case 'w': size = 2; break;
1771 case 'l': size = 4; break;
1772 case 'd': size = 8; break;
1773 case 'r': brev = !brev; break;
1774 case 'n': mnoread = 1; break;
1775 case '.': mnoread = 0; break;
1784 n = mread(adrs, val, size);
1785 printf("%.16x%c", adrs, brev? 'r': ' ');
1790 for (i = 0; i < n; ++i)
1791 printf("%.2x", val[i]);
1792 for (; i < size; ++i)
1793 printf("%s", fault_chars[fault_type]);
1800 for (i = 0; i < size; ++i)
1801 val[i] = n >> (i * 8);
1804 mwrite(adrs, val, size);
1817 else if( n == '\'' )
1819 for (i = 0; i < size; ++i)
1820 val[i] = n >> (i * 8);
1823 mwrite(adrs, val, size);
1860 adrs -= 1 << nslash;
1864 adrs += 1 << nslash;
1868 adrs += 1 << -nslash;
1872 adrs -= 1 << -nslash;
1875 scanhex((void *)&adrs);
1894 printf(memex_subcmd_help_string);
1909 case 'n': c = '\n'; break;
1910 case 'r': c = '\r'; break;
1911 case 'b': c = '\b'; break;
1912 case 't': c = '\t'; break;
1917 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
1918 || ('a' <= (c) && (c) <= 'f') \
1919 || ('A' <= (c) && (c) <= 'F'))
1926 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
1928 scanhex((void *)&adrs);
1935 else if (nidump > MAX_DUMP)
1937 adrs += ppc_inst_dump(adrs, nidump, 1);
1943 else if (ndump > MAX_DUMP)
1945 prdump(adrs, ndump);
1952 prdump(unsigned long adrs, long ndump)
1954 long n, m, c, r, nr;
1955 unsigned char temp[16];
1957 for (n = ndump; n > 0;) {
1958 printf("%.16lx", adrs);
1961 nr = mread(adrs, temp, r);
1963 for (m = 0; m < r; ++m) {
1964 if ((m & 7) == 0 && m > 0)
1967 printf("%.2x", temp[m]);
1969 printf("%s", fault_chars[fault_type]);
1976 for (m = 0; m < r; ++m) {
1979 putchar(' ' <= c && c <= '~'? c: '.');
1993 ppc_inst_dump(unsigned long adr, long count, int praddr)
1996 unsigned long first_adr;
1997 unsigned long inst, last_inst = 0;
1998 unsigned char val[4];
2001 for (first_adr = adr; count > 0; --count, adr += 4) {
2002 nr = mread(adr, val, 4);
2005 const char *x = fault_chars[fault_type];
2006 printf("%.16lx %s%s%s%s\n", adr, x, x, x, x);
2010 inst = GETWORD(val);
2011 if (adr > first_adr && inst == last_inst) {
2021 printf("%.16lx %.8x", adr, inst);
2023 print_insn_powerpc(inst, adr, 0); /* always returns 4 */
2026 return adr - first_adr;
2030 print_address(unsigned long addr)
2032 xmon_print_symbol(addr, "\t# ", "");
2037 * Memory operations - move, set, print differences
2039 static unsigned long mdest; /* destination address */
2040 static unsigned long msrc; /* source address */
2041 static unsigned long mval; /* byte value to set memory to */
2042 static unsigned long mcount; /* # bytes to affect */
2043 static unsigned long mdiffs; /* max # differences to print */
2048 scanhex((void *)&mdest);
2049 if( termch != '\n' )
2051 scanhex((void *)(cmd == 's'? &mval: &msrc));
2052 if( termch != '\n' )
2054 scanhex((void *)&mcount);
2057 memmove((void *)mdest, (void *)msrc, mcount);
2060 memset((void *)mdest, mval, mcount);
2063 if( termch != '\n' )
2065 scanhex((void *)&mdiffs);
2066 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2072 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2077 for( n = nb; n > 0; --n )
2078 if( *p1++ != *p2++ )
2079 if( ++prt <= maxpr )
2080 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2081 p1[-1], p2 - 1, p2[-1]);
2083 printf("Total of %d differences\n", prt);
2086 static unsigned mend;
2087 static unsigned mask;
2093 unsigned char val[4];
2096 scanhex((void *)&mdest);
2097 if (termch != '\n') {
2099 scanhex((void *)&mend);
2100 if (termch != '\n') {
2102 scanhex((void *)&mval);
2104 if (termch != '\n') termch = 0;
2105 scanhex((void *)&mask);
2109 for (a = mdest; a < mend; a += 4) {
2110 if (mread(a, val, 4) == 4
2111 && ((GETWORD(val) ^ mval) & mask) == 0) {
2112 printf("%.16x: %.16x\n", a, GETWORD(val));
2119 static unsigned long mskip = 0x1000;
2120 static unsigned long mlim = 0xffffffff;
2130 if (termch != '\n') termch = 0;
2132 if (termch != '\n') termch = 0;
2135 for (a = mdest; a < mlim; a += mskip) {
2136 ok = mread(a, &v, 1);
2138 printf("%.8x .. ", a);
2140 } else if (!ok && ook)
2141 printf("%.8x\n", a - mskip);
2147 printf("%.8x\n", a - mskip);
2150 /* Input scanning routines */
2161 while( c == ' ' || c == '\t' )
2167 static char *regnames[N_PTREGS] = {
2168 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2169 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2170 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2171 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2172 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", "softe",
2173 "trap", "dar", "dsisr", "res"
2177 scanhex(unsigned long *vp)
2184 /* parse register name */
2188 for (i = 0; i < sizeof(regname) - 1; ++i) {
2197 for (i = 0; i < N_PTREGS; ++i) {
2198 if (strcmp(regnames[i], regname) == 0) {
2199 if (xmon_regs == NULL) {
2200 printf("regs not available\n");
2203 *vp = ((unsigned long *)xmon_regs)[i];
2207 printf("invalid register name '%%%s'\n", regname);
2211 /* skip leading "0x" if any */
2225 } else if (c == '$') {
2227 for (i=0; i<63; i++) {
2236 *vp = kallsyms_lookup_name(tmpstr);
2238 printf("unknown symbol '%s'\n", tmpstr);
2274 if( '0' <= c && c <= '9' )
2276 if( 'A' <= c && c <= 'F' )
2277 return c - ('A' - 10);
2278 if( 'a' <= c && c <= 'f' )
2279 return c - ('a' - 10);
2284 getstring(char *s, int size)
2295 } while( c != ' ' && c != '\t' && c != '\n' );
2300 static char line[256];
2301 static char *lineptr;
2312 if (lineptr == NULL || *lineptr == 0) {
2313 if (fgets(line, sizeof(line), stdin) == NULL) {
2323 take_input(char *str)
2332 int type = inchar();
2334 static char tmp[64];
2339 xmon_print_symbol(addr, ": ", "\n");
2344 if (setjmp(bus_error_jmp) == 0) {
2345 catch_memory_errors = 1;
2347 addr = kallsyms_lookup_name(tmp);
2349 printf("%s: %lx\n", tmp, addr);
2351 printf("Symbol '%s' not found.\n", tmp);
2354 catch_memory_errors = 0;
2361 /* Print an address in numeric and symbolic form (if possible) */
2362 static void xmon_print_symbol(unsigned long address, const char *mid,
2366 const char *name = NULL;
2367 unsigned long offset, size;
2369 printf("%.16lx", address);
2370 if (setjmp(bus_error_jmp) == 0) {
2371 catch_memory_errors = 1;
2373 name = kallsyms_lookup(address, &size, &offset, &modname,
2376 /* wait a little while to see if we get a machine check */
2380 catch_memory_errors = 0;
2383 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2385 printf(" [%s]", modname);
2387 printf("%s", after);
2390 static void debug_trace(void)
2392 unsigned long val, cmd, on;
2396 /* show current state */
2398 printf("ppc64_debug_switch = 0x%lx\n", ppc64_debug_switch);
2399 for (i = 0; i < PPCDBG_NUM_FLAGS ;i++) {
2400 on = PPCDBG_BITVAL(i) & ppc64_debug_switch;
2401 printf("%02x %s %12s ", i, on ? "on " : "off", trace_names[i] ? trace_names[i] : "");
2402 if (((i+1) % 3) == 0)
2408 while (cmd != '\n') {
2409 on = 1; /* default if no sign given */
2410 while (cmd == '+' || cmd == '-') {
2413 if (cmd == ' ' || cmd == '\n') { /* Turn on or off based on + or - */
2414 ppc64_debug_switch = on ? PPCDBG_ALL:PPCDBG_NONE;
2415 printf("Setting all values to %s...\n", on ? "on" : "off");
2416 if (cmd == '\n') return;
2417 else cmd = skipbl();
2422 termch = cmd; /* not +/- ... let scanhex see it */
2423 scanhex((void *)&val);
2425 printf("Value %x out of range:\n", val);
2429 ppc64_debug_switch |= PPCDBG_BITVAL(val);
2430 printf("enable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
2432 ppc64_debug_switch &= ~PPCDBG_BITVAL(val);
2433 printf("disable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
2439 static void dump_slb(void)
2444 printf("SLB contents of cpu %x\n", smp_processor_id());
2446 for (i = 0; i < SLB_NUM_ENTRIES; i++) {
2447 asm volatile("slbmfee %0,%1" : "=r" (tmp) : "r" (i));
2448 printf("%02d %016lx ", i, tmp);
2450 asm volatile("slbmfev %0,%1" : "=r" (tmp) : "r" (i));
2451 printf("%016lx\n", tmp);
2455 static void dump_stab(void)
2458 unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2460 printf("Segment table contents of cpu %x\n", smp_processor_id());
2462 for (i = 0; i < PAGE_SIZE/16; i++) {
2469 printf("%03d %016lx ", i, a);
2470 printf("%016lx\n", b);
2475 void xmon_init(void)
2478 __debugger_ipi = xmon_ipi;
2479 __debugger_bpt = xmon_bpt;
2480 __debugger_sstep = xmon_sstep;
2481 __debugger_iabr_match = xmon_iabr_match;
2482 __debugger_dabr_match = xmon_dabr_match;
2483 __debugger_fault_handler = xmon_fault_handler;
2486 void dump_segments(void)
2488 if (cur_cpu_spec->cpu_features & CPU_FTR_SLB)