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>
35 #include <asm/hvcall.h>
40 #define scanhex xmon_scanhex
41 #define skipbl xmon_skipbl
44 cpumask_t cpus_in_xmon = CPU_MASK_NONE;
45 static unsigned long xmon_taken = 1;
46 static int xmon_owner;
48 #endif /* CONFIG_SMP */
50 static unsigned long in_xmon = 0;
52 static unsigned long adrs;
54 #define MAX_DUMP (128 * 1024)
55 static unsigned long ndump = 64;
56 static unsigned long nidump = 16;
57 static unsigned long ncsum = 4096;
59 static char tmpstr[128];
61 #define JMP_BUF_LEN (184/sizeof(long))
62 static long bus_error_jmp[JMP_BUF_LEN];
63 static int catch_memory_errors;
64 static long *xmon_fault_jmp[NR_CPUS];
65 #define setjmp xmon_setjmp
66 #define longjmp xmon_longjmp
68 /* Breakpoint stuff */
70 unsigned long address;
71 unsigned int instr[2];
77 /* Bits in bpt.enabled */
78 #define BP_IABR_TE 1 /* IABR translation enabled */
84 static struct bpt bpts[NBPTS];
85 static struct bpt dabr;
86 static struct bpt *iabr;
87 static unsigned bpinstr = 0x7fe00008; /* trap */
89 #define BP_NUM(bp) ((bp) - bpts + 1)
92 static int cmds(struct pt_regs *);
93 static int mread(unsigned long, void *, int);
94 static int mwrite(unsigned long, void *, int);
95 static int handle_fault(struct pt_regs *);
96 static void byterev(unsigned char *, int);
97 static void memex(void);
98 static int bsesc(void);
99 static void dump(void);
100 static void prdump(unsigned long, long);
101 static int ppc_inst_dump(unsigned long, long, int);
102 void print_address(unsigned long);
103 static void backtrace(struct pt_regs *);
104 static void excprint(struct pt_regs *);
105 static void prregs(struct pt_regs *);
106 static void memops(int);
107 static void memlocate(void);
108 static void memzcan(void);
109 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
111 int scanhex(unsigned long *valp);
112 static void scannl(void);
113 static int hexdigit(int);
114 void getstring(char *, int);
115 static void flush_input(void);
116 static int inchar(void);
117 static void take_input(char *);
118 static unsigned long read_spr(int);
119 static void write_spr(int, unsigned long);
120 static void super_regs(void);
121 static void remove_bpts(void);
122 static void insert_bpts(void);
123 static void remove_cpu_bpts(void);
124 static void insert_cpu_bpts(void);
125 static struct bpt *at_breakpoint(unsigned long pc);
126 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
127 static int do_step(struct pt_regs *);
128 static void bpt_cmds(void);
129 static void cacheflush(void);
130 static int cpu_cmd(void);
131 static void csum(void);
132 static void bootcmds(void);
133 void dump_segments(void);
134 static void symbol_lookup(void);
135 static void xmon_print_symbol(unsigned long address, const char *mid,
137 static const char *getvecname(unsigned long vec);
139 static void debug_trace(void);
141 extern int print_insn_powerpc(unsigned long, unsigned long, int);
142 extern void printf(const char *fmt, ...);
143 extern void xmon_vfprintf(void *f, const char *fmt, va_list ap);
144 extern int xmon_putc(int c, void *f);
145 extern int putchar(int ch);
146 extern int xmon_read_poll(void);
147 extern int setjmp(long *);
148 extern void longjmp(long *, int);
149 extern unsigned long _ASR;
151 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
153 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
154 || ('a' <= (c) && (c) <= 'f') \
155 || ('A' <= (c) && (c) <= 'F'))
156 #define isalnum(c) (('0' <= (c) && (c) <= '9') \
157 || ('a' <= (c) && (c) <= 'z') \
158 || ('A' <= (c) && (c) <= 'Z'))
159 #define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
161 static char *help_string = "\
163 b show breakpoints\n\
164 bd set data breakpoint\n\
165 bi set instruction breakpoint\n\
166 bc clear breakpoint\n"
169 c print cpus stopped in xmon\n\
170 c# try to switch to cpu number h (in hex)\n"
175 di dump instructions\n\
176 df dump float values\n\
177 dd dump double values\n\
178 e print exception information\n\
180 la lookup symbol+offset of specified address\n\
181 ls lookup address of specified symbol\n\
182 m examine/change memory\n\
183 mm move a block of memory\n\
184 ms set a block of memory\n\
185 md compare two blocks of memory\n\
186 ml locate a block of memory\n\
187 mz zero a block of memory\n\
188 mi show information about memory allocation\n\
189 p show the task list\n\
192 S print special registers\n\
194 T Enable/Disable PPCDBG flags\n\
195 x exit monitor and recover\n\
196 X exit monitor and dont recover\n\
197 u dump segment table or SLB\n\
204 static struct pt_regs *xmon_regs;
206 extern inline void sync(void)
208 asm volatile("sync; isync");
211 /* (Ref: 64-bit PowerPC ELF ABI Spplement; Ian Lance Taylor, Zembu Labs).
212 A PPC stack frame looks like this:
219 Parameter save area (SP+48)
220 TOC save area (SP+40)
221 link editor doubleword (SP+32)
222 compiler doubleword (SP+24)
227 Note that the LR (ret addr) may not be saved in the current frame if
228 no functions have been called from the current function.
232 * Disable surveillance (the service processor watchdog function)
233 * while we are in xmon.
234 * XXX we should re-enable it when we leave. :)
236 #define SURVEILLANCE_TOKEN 9000
238 static inline void disable_surveillance(void)
240 #ifdef CONFIG_PPC_PSERIES
241 /* Since this can't be a module, args should end up below 4GB. */
242 static struct rtas_args args;
245 * At this point we have got all the cpus we can into
246 * xmon, so there is hopefully no other cpu calling RTAS
247 * at the moment, even though we don't take rtas.lock.
248 * If we did try to take rtas.lock there would be a
249 * real possibility of deadlock.
251 args.token = rtas_token("set-indicator");
252 if (args.token == RTAS_UNKNOWN_SERVICE)
256 args.rets = &args.args[3];
257 args.args[0] = SURVEILLANCE_TOKEN;
260 enter_rtas(__pa(&args));
261 #endif /* CONFIG_PPC_PSERIES */
265 static int xmon_speaker;
267 static void get_output_lock(void)
269 int me = smp_processor_id() + 0x100;
270 int last_speaker = 0, prev;
273 if (xmon_speaker == me)
276 if (xmon_speaker == 0) {
277 last_speaker = cmpxchg(&xmon_speaker, 0, me);
278 if (last_speaker == 0)
282 while (xmon_speaker == last_speaker) {
285 /* hostile takeover */
286 prev = cmpxchg(&xmon_speaker, last_speaker, me);
287 if (prev == last_speaker)
294 static void release_output_lock(void)
300 int xmon_core(struct pt_regs *regs, int fromipi)
305 long recurse_jmp[JMP_BUF_LEN];
306 unsigned long offset;
310 unsigned long timeout;
314 set_msrd(msr & ~MSR_EE); /* disable interrupts */
316 bp = in_breakpoint_table(regs->nip, &offset);
318 regs->nip = bp->address + offset;
319 atomic_dec(&bp->ref_count);
325 cpu = smp_processor_id();
326 if (cpu_isset(cpu, cpus_in_xmon)) {
329 printf("cpu 0x%x: Exception %lx %s in xmon, "
330 "returning to main loop\n",
331 cpu, regs->trap, getvecname(TRAP(regs)));
332 release_output_lock();
333 longjmp(xmon_fault_jmp[cpu], 1);
336 if (setjmp(recurse_jmp) != 0) {
337 if (!in_xmon || !xmon_gate) {
339 printf("xmon: WARNING: bad recursive fault "
340 "on cpu 0x%x\n", cpu);
341 release_output_lock();
344 secondary = !(xmon_taken && cpu == xmon_owner);
348 xmon_fault_jmp[cpu] = recurse_jmp;
349 cpu_set(cpu, cpus_in_xmon);
352 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
353 bp = at_breakpoint(regs->nip);
354 if (bp || (regs->msr & MSR_RI) == 0)
361 printf("cpu 0x%x stopped at breakpoint 0x%x (",
363 xmon_print_symbol(regs->nip, " ", ")\n");
365 if ((regs->msr & MSR_RI) == 0)
366 printf("WARNING: exception is not recoverable, "
368 release_output_lock();
373 while (secondary && !xmon_gate) {
377 secondary = test_and_set_bit(0, &in_xmon);
382 if (!secondary && !xmon_gate) {
383 /* we are the first cpu to come in */
384 /* interrupt other cpu(s) */
385 int ncpus = num_online_cpus();
390 smp_send_debugger_break(MSG_ALL_BUT_SELF);
391 /* wait for other cpus to come in */
392 for (timeout = 100000000; timeout != 0; --timeout) {
393 if (cpus_weight(cpus_in_xmon) >= ncpus)
399 disable_surveillance();
400 /* for breakpoint or single step, print the current instr. */
401 if (bp || TRAP(regs) == 0xd00)
402 ppc_inst_dump(regs->nip, 1, 0);
403 printf("enter ? for help\n");
412 if (cpu == xmon_owner) {
413 if (!test_and_set_bit(0, &xmon_taken)) {
418 while (cpu == xmon_owner)
432 /* have switched to some other cpu */
437 cpu_clear(cpu, cpus_in_xmon);
438 xmon_fault_jmp[cpu] = NULL;
441 /* UP is simple... */
443 printf("Exception %lx %s in xmon, returning to main loop\n",
444 regs->trap, getvecname(TRAP(regs)));
445 longjmp(xmon_fault_jmp[0], 1);
447 if (setjmp(recurse_jmp) == 0) {
448 xmon_fault_jmp[0] = recurse_jmp;
452 bp = at_breakpoint(regs->nip);
454 printf("Stopped at breakpoint %x (", BP_NUM(bp));
455 xmon_print_symbol(regs->nip, " ", ")\n");
457 if ((regs->msr & MSR_RI) == 0)
458 printf("WARNING: exception is not recoverable, "
461 disable_surveillance();
462 /* for breakpoint or single step, print the current instr. */
463 if (bp || TRAP(regs) == 0xd00)
464 ppc_inst_dump(regs->nip, 1, 0);
465 printf("enter ? for help\n");
474 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
475 bp = at_breakpoint(regs->nip);
477 int stepped = emulate_step(regs, bp->instr[0]);
479 regs->nip = (unsigned long) &bp->instr[0];
480 atomic_inc(&bp->ref_count);
481 } else if (stepped < 0) {
482 printf("Couldn't single-step %s instruction\n",
483 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
490 set_msrd(msr); /* restore interrupt enable */
495 int xmon(struct pt_regs *excp)
500 /* Ok, grab regs as they are now.
501 This won't do a particularily good job because the
502 prologue has already been executed.
503 ToDo: We could reach back into the callers save
504 area to do a better job of representing the
507 asm volatile ("std 0,0(%0)\n\
538 std 31,248(%0)" : : "b" (®s));
540 regs.nip = regs.link = ((unsigned long *)(regs.gpr[1]))[2];
541 regs.msr = get_msr();
542 regs.ctr = get_ctr();
543 regs.xer = get_xer();
548 return xmon_core(excp, 0);
551 int xmon_bpt(struct pt_regs *regs)
554 unsigned long offset;
556 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
559 /* Are we at the trap at bp->instr[1] for some bp? */
560 bp = in_breakpoint_table(regs->nip, &offset);
561 if (bp != NULL && offset == 4) {
562 regs->nip = bp->address + 4;
563 atomic_dec(&bp->ref_count);
567 /* Are we at a breakpoint? */
568 bp = at_breakpoint(regs->nip);
577 int xmon_sstep(struct pt_regs *regs)
585 int xmon_dabr_match(struct pt_regs *regs)
587 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
589 if (dabr.enabled == 0)
595 int xmon_iabr_match(struct pt_regs *regs)
597 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
605 int xmon_ipi(struct pt_regs *regs)
608 if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
614 int xmon_fault_handler(struct pt_regs *regs)
617 unsigned long offset;
619 if (in_xmon && catch_memory_errors)
620 handle_fault(regs); /* doesn't return */
622 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
623 bp = in_breakpoint_table(regs->nip, &offset);
625 regs->nip = bp->address + offset;
626 atomic_dec(&bp->ref_count);
633 static struct bpt *at_breakpoint(unsigned long pc)
639 for (i = 0; i < NBPTS; ++i, ++bp)
640 if (bp->enabled && pc == bp->address)
645 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
649 off = nip - (unsigned long) bpts;
650 if (off >= sizeof(bpts))
652 off %= sizeof(struct bpt);
653 if (off != offsetof(struct bpt, instr[0])
654 && off != offsetof(struct bpt, instr[1]))
656 *offp = off - offsetof(struct bpt, instr[0]);
657 return (struct bpt *) (nip - off);
660 static struct bpt *new_breakpoint(unsigned long a)
665 bp = at_breakpoint(a);
669 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
670 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
672 bp->instr[1] = bpinstr;
673 store_inst(&bp->instr[1]);
678 printf("Sorry, no free breakpoints. Please clear one first.\n");
682 static void insert_bpts(void)
688 for (i = 0; i < NBPTS; ++i, ++bp) {
689 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
691 if (mread(bp->address, &bp->instr[0], 4) != 4) {
692 printf("Couldn't read instruction at %lx, "
693 "disabling breakpoint there\n", bp->address);
697 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
698 printf("Breakpoint at %lx is on an mtmsrd or rfid "
699 "instruction, disabling it\n", bp->address);
703 store_inst(&bp->instr[0]);
704 if (bp->enabled & BP_IABR)
706 if (mwrite(bp->address, &bpinstr, 4) != 4) {
707 printf("Couldn't write instruction at %lx, "
708 "disabling breakpoint there\n", bp->address);
709 bp->enabled &= ~BP_TRAP;
712 store_inst((void *)bp->address);
716 static void insert_cpu_bpts(void)
719 set_dabr(dabr.address | (dabr.enabled & 7));
720 if (iabr && cpu_has_feature(CPU_FTR_IABR))
721 set_iabr(iabr->address
722 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
725 static void remove_bpts(void)
732 for (i = 0; i < NBPTS; ++i, ++bp) {
733 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
735 if (mread(bp->address, &instr, 4) == 4
737 && mwrite(bp->address, &bp->instr, 4) != 4)
738 printf("Couldn't remove breakpoint at %lx\n",
741 store_inst((void *)bp->address);
745 static void remove_cpu_bpts(void)
748 if (cpu_has_feature(CPU_FTR_IABR))
752 /* Command interpreting routine */
753 static char *last_cmd;
756 cmds(struct pt_regs *excp)
764 printf("%x:", smp_processor_id());
765 #endif /* CONFIG_SMP */
772 if (last_cmd == NULL)
774 take_input(last_cmd);
808 prregs(excp); /* print regs */
856 printf("Unrecognized command: ");
858 if (' ' < cmd && cmd <= '~')
861 printf("\\x%x", cmd);
863 } while (cmd != '\n');
864 printf(" (type ? for help)\n");
871 * Step a single instruction.
872 * Some instructions we emulate, others we execute with MSR_SE set.
874 static int do_step(struct pt_regs *regs)
879 /* check we are in 64-bit kernel mode, translation enabled */
880 if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
881 if (mread(regs->nip, &instr, 4) == 4) {
882 stepped = emulate_step(regs, instr);
884 printf("Couldn't single-step %s instruction\n",
885 (IS_RFID(instr)? "rfid": "mtmsrd"));
889 regs->trap = 0xd00 | (regs->trap & 1);
890 printf("stepped to ");
891 xmon_print_symbol(regs->nip, " ", "\n");
892 ppc_inst_dump(regs->nip, 1, 0);
901 static void bootcmds(void)
907 ppc_md.restart(NULL);
914 static int cpu_cmd(void)
921 if (!scanhex(&cpu)) {
922 /* print cpus waiting or in xmon */
923 printf("cpus stopped:");
925 for (cpu = 0; cpu < NR_CPUS; ++cpu) {
926 if (cpu_isset(cpu, cpus_in_xmon)) {
932 printf("-%x", cpu - 1);
937 printf("-%x", NR_CPUS - 1);
941 /* try to switch to cpu specified */
942 if (!cpu_isset(cpu, cpus_in_xmon)) {
943 printf("cpu 0x%x isn't in xmon\n", cpu);
950 while (!xmon_taken) {
951 if (--timeout == 0) {
952 if (test_and_set_bit(0, &xmon_taken))
954 /* take control back */
956 xmon_owner = smp_processor_id();
957 printf("cpu %u didn't take control\n", cpu);
965 #endif /* CONFIG_SMP */
968 static unsigned short fcstab[256] = {
969 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
970 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
971 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
972 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
973 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
974 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
975 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
976 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
977 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
978 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
979 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
980 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
981 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
982 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
983 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
984 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
985 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
986 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
987 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
988 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
989 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
990 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
991 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
992 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
993 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
994 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
995 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
996 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
997 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
998 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
999 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1000 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1003 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1012 if (!scanhex(&adrs))
1014 if (!scanhex(&ncsum))
1017 for (i = 0; i < ncsum; ++i) {
1018 if (mread(adrs+i, &v, 1) == 0) {
1019 printf("csum stopped at %x\n", adrs+i);
1024 printf("%x\n", fcs);
1028 * Check if this is a suitable place to put a breakpoint.
1030 static long check_bp_loc(unsigned long addr)
1035 if (addr < KERNELBASE) {
1036 printf("Breakpoints may only be placed at kernel addresses\n");
1039 if (!mread(addr, &instr, sizeof(instr))) {
1040 printf("Can't read instruction at address %lx\n", addr);
1043 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1044 printf("Breakpoints may not be placed on mtmsrd or rfid "
1051 static char *breakpoint_help_string =
1052 "Breakpoint command usage:\n"
1053 "b show breakpoints\n"
1054 "b <addr> [cnt] set breakpoint at given instr addr\n"
1055 "bc clear all breakpoints\n"
1056 "bc <n/addr> clear breakpoint number n or at addr\n"
1057 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1058 "bd <addr> [cnt] set hardware data breakpoint\n"
1068 const char badaddr[] = "Only kernel addresses are permitted "
1069 "for breakpoints\n";
1073 case 'd': /* bd - hardware data breakpoint */
1078 else if (cmd == 'w')
1084 if (scanhex(&dabr.address)) {
1085 if (dabr.address < KERNELBASE) {
1090 dabr.enabled = mode | BP_DABR;
1094 case 'i': /* bi - hardware instr breakpoint */
1095 if (!cpu_has_feature(CPU_FTR_IABR)) {
1096 printf("Hardware instruction breakpoint "
1097 "not supported on this cpu\n");
1101 iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1106 if (!check_bp_loc(a))
1108 bp = new_breakpoint(a);
1110 bp->enabled |= BP_IABR | BP_IABR_TE;
1117 /* clear all breakpoints */
1118 for (i = 0; i < NBPTS; ++i)
1119 bpts[i].enabled = 0;
1122 printf("All breakpoints cleared\n");
1126 if (a <= NBPTS && a >= 1) {
1127 /* assume a breakpoint number */
1128 bp = &bpts[a-1]; /* bp nums are 1 based */
1130 /* assume a breakpoint address */
1131 bp = at_breakpoint(a);
1133 printf("No breakpoint at %x\n", a);
1138 printf("Cleared breakpoint %x (", BP_NUM(bp));
1139 xmon_print_symbol(bp->address, " ", ")\n");
1147 printf(breakpoint_help_string);
1152 /* print all breakpoints */
1153 printf(" type address\n");
1155 printf(" data %.16lx [", dabr.address);
1156 if (dabr.enabled & 1)
1158 if (dabr.enabled & 2)
1162 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1165 printf("%2x %s ", BP_NUM(bp),
1166 (bp->enabled & BP_IABR)? "inst": "trap");
1167 xmon_print_symbol(bp->address, " ", "\n");
1172 if (!check_bp_loc(a))
1174 bp = new_breakpoint(a);
1176 bp->enabled |= BP_TRAP;
1181 /* Very cheap human name for vector lookup. */
1183 const char *getvecname(unsigned long vec)
1188 case 0x100: ret = "(System Reset)"; break;
1189 case 0x200: ret = "(Machine Check)"; break;
1190 case 0x300: ret = "(Data Access)"; break;
1191 case 0x380: ret = "(Data SLB Access)"; break;
1192 case 0x400: ret = "(Instruction Access)"; break;
1193 case 0x480: ret = "(Instruction SLB Access)"; break;
1194 case 0x500: ret = "(Hardware Interrupt)"; break;
1195 case 0x600: ret = "(Alignment)"; break;
1196 case 0x700: ret = "(Program Check)"; break;
1197 case 0x800: ret = "(FPU Unavailable)"; break;
1198 case 0x900: ret = "(Decrementer)"; break;
1199 case 0xc00: ret = "(System Call)"; break;
1200 case 0xd00: ret = "(Single Step)"; break;
1201 case 0xf00: ret = "(Performance Monitor)"; break;
1202 case 0xf20: ret = "(Altivec Unavailable)"; break;
1203 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1209 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1210 unsigned long *endp)
1212 unsigned long size, offset;
1216 *startp = *endp = 0;
1219 if (setjmp(bus_error_jmp) == 0) {
1220 catch_memory_errors = 1;
1222 name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr);
1224 *startp = pc - offset;
1225 *endp = pc - offset + size;
1229 catch_memory_errors = 0;
1232 static int xmon_depth_to_print = 64;
1234 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1238 unsigned long newsp;
1239 unsigned long marker;
1241 struct pt_regs regs;
1244 if (sp < PAGE_OFFSET) {
1246 printf("SP (%lx) is in userspace\n", sp);
1250 if (!mread(sp + 16, &ip, sizeof(unsigned long))
1251 || !mread(sp, &newsp, sizeof(unsigned long))) {
1252 printf("Couldn't read stack frame at %lx\n", sp);
1257 * For the first stack frame, try to work out if
1258 * LR and/or the saved LR value in the bottommost
1259 * stack frame are valid.
1261 if ((pc | lr) != 0) {
1262 unsigned long fnstart, fnend;
1263 unsigned long nextip;
1266 get_function_bounds(pc, &fnstart, &fnend);
1269 mread(newsp + 16, &nextip,
1270 sizeof(unsigned long));
1272 if (lr < PAGE_OFFSET
1273 || (fnstart <= lr && lr < fnend))
1275 } else if (lr == nextip) {
1277 } else if (lr >= PAGE_OFFSET
1278 && !(fnstart <= lr && lr < fnend)) {
1279 printf("[link register ] ");
1280 xmon_print_symbol(lr, " ", "\n");
1283 printf("[%.16lx] ", sp);
1284 xmon_print_symbol(ip, " ", " (unreliable)\n");
1289 printf("[%.16lx] ", sp);
1290 xmon_print_symbol(ip, " ", "\n");
1293 /* Look for "regshere" marker to see if this is
1294 an exception frame. */
1295 if (mread(sp + 0x60, &marker, sizeof(unsigned long))
1296 && marker == 0x7265677368657265ul) {
1297 if (mread(sp + 0x70, ®s, sizeof(regs))
1299 printf("Couldn't read registers at %lx\n",
1303 printf("--- Exception: %lx %s at ", regs.trap,
1304 getvecname(TRAP(®s)));
1307 xmon_print_symbol(pc, " ", "\n");
1314 } while (count++ < xmon_depth_to_print);
1317 static void backtrace(struct pt_regs *excp)
1322 xmon_show_stack(sp, 0, 0);
1324 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1328 static void print_bug_trap(struct pt_regs *regs)
1330 struct bug_entry *bug;
1333 if (regs->msr & MSR_PR)
1334 return; /* not in kernel */
1335 addr = regs->nip; /* address of trap instruction */
1336 if (addr < PAGE_OFFSET)
1338 bug = find_bug(regs->nip);
1341 if (bug->line & BUG_WARNING_TRAP)
1344 printf("kernel BUG in %s at %s:%d!\n",
1345 bug->function, bug->file, (unsigned int)bug->line);
1348 void excprint(struct pt_regs *fp)
1353 printf("cpu 0x%x: ", smp_processor_id());
1354 #endif /* CONFIG_SMP */
1357 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1359 xmon_print_symbol(fp->nip, ": ", "\n");
1361 printf(" lr: ", fp->link);
1362 xmon_print_symbol(fp->link, ": ", "\n");
1364 printf(" sp: %lx\n", fp->gpr[1]);
1365 printf(" msr: %lx\n", fp->msr);
1367 if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1368 printf(" dar: %lx\n", fp->dar);
1370 printf(" dsisr: %lx\n", fp->dsisr);
1373 printf(" current = 0x%lx\n", current);
1374 printf(" paca = 0x%lx\n", get_paca());
1376 printf(" pid = %ld, comm = %s\n",
1377 current->pid, current->comm);
1384 void prregs(struct pt_regs *fp)
1388 struct pt_regs regs;
1390 if (scanhex(&base)) {
1391 if (setjmp(bus_error_jmp) == 0) {
1392 catch_memory_errors = 1;
1394 regs = *(struct pt_regs *)base;
1398 catch_memory_errors = 0;
1399 printf("*** Error reading registers from %.16lx\n",
1403 catch_memory_errors = 0;
1407 if (FULL_REGS(fp)) {
1408 for (n = 0; n < 16; ++n)
1409 printf("R%.2ld = %.16lx R%.2ld = %.16lx\n",
1410 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1412 for (n = 0; n < 7; ++n)
1413 printf("R%.2ld = %.16lx R%.2ld = %.16lx\n",
1414 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1417 xmon_print_symbol(fp->nip, " ", "\n");
1419 xmon_print_symbol(fp->link, " ", "\n");
1420 printf("msr = %.16lx cr = %.8lx\n", fp->msr, fp->ccr);
1421 printf("ctr = %.16lx xer = %.16lx trap = %8lx\n",
1422 fp->ctr, fp->xer, fp->trap);
1425 void cacheflush(void)
1428 unsigned long nflush;
1433 scanhex((void *)&adrs);
1438 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1439 if (setjmp(bus_error_jmp) == 0) {
1440 catch_memory_errors = 1;
1444 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1445 cflush((void *) adrs);
1447 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1448 cinval((void *) adrs);
1451 /* wait a little while to see if we get a machine check */
1454 catch_memory_errors = 0;
1460 unsigned int instrs[2];
1461 unsigned long (*code)(void);
1462 unsigned long opd[3];
1463 unsigned long ret = -1UL;
1465 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1466 instrs[1] = 0x4e800020;
1467 opd[0] = (unsigned long)instrs;
1471 store_inst(instrs+1);
1472 code = (unsigned long (*)(void)) opd;
1474 if (setjmp(bus_error_jmp) == 0) {
1475 catch_memory_errors = 1;
1481 /* wait a little while to see if we get a machine check */
1490 write_spr(int n, unsigned long val)
1492 unsigned int instrs[2];
1493 unsigned long (*code)(unsigned long);
1494 unsigned long opd[3];
1496 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1497 instrs[1] = 0x4e800020;
1498 opd[0] = (unsigned long)instrs;
1502 store_inst(instrs+1);
1503 code = (unsigned long (*)(unsigned long)) opd;
1505 if (setjmp(bus_error_jmp) == 0) {
1506 catch_memory_errors = 1;
1512 /* wait a little while to see if we get a machine check */
1518 static unsigned long regno;
1519 extern char exc_prolog;
1520 extern char dec_exc;
1527 #ifdef CONFIG_PPC_ISERIES
1528 struct paca_struct *ptrPaca = NULL;
1529 struct lppaca *ptrLpPaca = NULL;
1530 struct ItLpRegSave *ptrLpRegSave = NULL;
1535 unsigned long sp, toc;
1536 asm("mr %0,1" : "=r" (sp) :);
1537 asm("mr %0,2" : "=r" (toc) :);
1539 printf("msr = %.16lx sprg0= %.16lx\n", get_msr(), get_sprg0());
1540 printf("pvr = %.16lx sprg1= %.16lx\n", get_pvr(), get_sprg1());
1541 printf("dec = %.16lx sprg2= %.16lx\n", get_dec(), get_sprg2());
1542 printf("sp = %.16lx sprg3= %.16lx\n", sp, get_sprg3());
1543 printf("toc = %.16lx dar = %.16lx\n", toc, get_dar());
1544 printf("srr0 = %.16lx srr1 = %.16lx\n", get_srr0(), get_srr1());
1545 #ifdef CONFIG_PPC_ISERIES
1546 // Dump out relevant Paca data areas.
1548 ptrPaca = get_paca();
1550 printf(" Local Processor Control Area (LpPaca): \n");
1551 ptrLpPaca = ptrPaca->lppaca_ptr;
1552 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1553 ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
1554 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1555 ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
1556 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
1558 printf(" Local Processor Register Save Area (LpRegSave): \n");
1559 ptrLpRegSave = ptrPaca->reg_save_ptr;
1560 printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n",
1561 ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
1562 printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n",
1563 ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
1564 printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n",
1565 ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
1574 val = read_spr(regno);
1576 write_spr(regno, val);
1579 printf("spr %lx = %lx\n", regno, read_spr(regno));
1591 * Stuff for reading and writing memory safely
1594 mread(unsigned long adrs, void *buf, int size)
1600 if (setjmp(bus_error_jmp) == 0) {
1601 catch_memory_errors = 1;
1607 *(short *)q = *(short *)p;
1610 *(int *)q = *(int *)p;
1613 *(long *)q = *(long *)p;
1616 for( ; n < size; ++n) {
1622 /* wait a little while to see if we get a machine check */
1626 catch_memory_errors = 0;
1631 mwrite(unsigned long adrs, void *buf, int size)
1637 if (setjmp(bus_error_jmp) == 0) {
1638 catch_memory_errors = 1;
1644 *(short *)p = *(short *)q;
1647 *(int *)p = *(int *)q;
1650 *(long *)p = *(long *)q;
1653 for ( ; n < size; ++n) {
1659 /* wait a little while to see if we get a machine check */
1663 printf("*** Error writing address %x\n", adrs + n);
1665 catch_memory_errors = 0;
1669 static int fault_type;
1670 static char *fault_chars[] = { "--", "**", "##" };
1673 handle_fault(struct pt_regs *regs)
1675 switch (TRAP(regs)) {
1687 longjmp(bus_error_jmp, 1);
1692 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1695 byterev(unsigned char *val, int size)
1701 SWAP(val[0], val[1], t);
1704 SWAP(val[0], val[3], t);
1705 SWAP(val[1], val[2], t);
1707 case 8: /* is there really any use for this? */
1708 SWAP(val[0], val[7], t);
1709 SWAP(val[1], val[6], t);
1710 SWAP(val[2], val[5], t);
1711 SWAP(val[3], val[4], t);
1719 static char *memex_help_string =
1720 "Memory examine command usage:\n"
1721 "m [addr] [flags] examine/change memory\n"
1722 " addr is optional. will start where left off.\n"
1723 " flags may include chars from this set:\n"
1724 " b modify by bytes (default)\n"
1725 " w modify by words (2 byte)\n"
1726 " l modify by longs (4 byte)\n"
1727 " d modify by doubleword (8 byte)\n"
1728 " r toggle reverse byte order mode\n"
1729 " n do not read memory (for i/o spaces)\n"
1730 " . ok to read (default)\n"
1731 "NOTE: flags are saved as defaults\n"
1734 static char *memex_subcmd_help_string =
1735 "Memory examine subcommands:\n"
1736 " hexval write this val to current location\n"
1737 " 'string' write chars from string to this location\n"
1738 " ' increment address\n"
1739 " ^ decrement address\n"
1740 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1741 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1742 " ` clear no-read flag\n"
1743 " ; stay at this addr\n"
1744 " v change to byte mode\n"
1745 " w change to word (2 byte) mode\n"
1746 " l change to long (4 byte) mode\n"
1747 " u change to doubleword (8 byte) mode\n"
1748 " m addr change current addr\n"
1749 " n toggle no-read flag\n"
1750 " r toggle byte reverse flag\n"
1751 " < count back up count bytes\n"
1752 " > count skip forward count bytes\n"
1753 " x exit this mode\n"
1759 int cmd, inc, i, nslash;
1761 unsigned char val[16];
1763 scanhex((void *)&adrs);
1766 printf(memex_help_string);
1772 while ((cmd = skipbl()) != '\n') {
1774 case 'b': size = 1; break;
1775 case 'w': size = 2; break;
1776 case 'l': size = 4; break;
1777 case 'd': size = 8; break;
1778 case 'r': brev = !brev; break;
1779 case 'n': mnoread = 1; break;
1780 case '.': mnoread = 0; break;
1789 n = mread(adrs, val, size);
1790 printf("%.16x%c", adrs, brev? 'r': ' ');
1795 for (i = 0; i < n; ++i)
1796 printf("%.2x", val[i]);
1797 for (; i < size; ++i)
1798 printf("%s", fault_chars[fault_type]);
1805 for (i = 0; i < size; ++i)
1806 val[i] = n >> (i * 8);
1809 mwrite(adrs, val, size);
1822 else if( n == '\'' )
1824 for (i = 0; i < size; ++i)
1825 val[i] = n >> (i * 8);
1828 mwrite(adrs, val, size);
1865 adrs -= 1 << nslash;
1869 adrs += 1 << nslash;
1873 adrs += 1 << -nslash;
1877 adrs -= 1 << -nslash;
1880 scanhex((void *)&adrs);
1899 printf(memex_subcmd_help_string);
1914 case 'n': c = '\n'; break;
1915 case 'r': c = '\r'; break;
1916 case 'b': c = '\b'; break;
1917 case 't': c = '\t'; break;
1922 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
1923 || ('a' <= (c) && (c) <= 'f') \
1924 || ('A' <= (c) && (c) <= 'F'))
1931 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
1933 scanhex((void *)&adrs);
1940 else if (nidump > MAX_DUMP)
1942 adrs += ppc_inst_dump(adrs, nidump, 1);
1948 else if (ndump > MAX_DUMP)
1950 prdump(adrs, ndump);
1957 prdump(unsigned long adrs, long ndump)
1959 long n, m, c, r, nr;
1960 unsigned char temp[16];
1962 for (n = ndump; n > 0;) {
1963 printf("%.16lx", adrs);
1966 nr = mread(adrs, temp, r);
1968 for (m = 0; m < r; ++m) {
1969 if ((m & 7) == 0 && m > 0)
1972 printf("%.2x", temp[m]);
1974 printf("%s", fault_chars[fault_type]);
1981 for (m = 0; m < r; ++m) {
1984 putchar(' ' <= c && c <= '~'? c: '.');
1998 ppc_inst_dump(unsigned long adr, long count, int praddr)
2001 unsigned long first_adr;
2002 unsigned long inst, last_inst = 0;
2003 unsigned char val[4];
2006 for (first_adr = adr; count > 0; --count, adr += 4) {
2007 nr = mread(adr, val, 4);
2010 const char *x = fault_chars[fault_type];
2011 printf("%.16lx %s%s%s%s\n", adr, x, x, x, x);
2015 inst = GETWORD(val);
2016 if (adr > first_adr && inst == last_inst) {
2026 printf("%.16lx %.8x", adr, inst);
2028 print_insn_powerpc(inst, adr, 0); /* always returns 4 */
2031 return adr - first_adr;
2035 print_address(unsigned long addr)
2037 xmon_print_symbol(addr, "\t# ", "");
2042 * Memory operations - move, set, print differences
2044 static unsigned long mdest; /* destination address */
2045 static unsigned long msrc; /* source address */
2046 static unsigned long mval; /* byte value to set memory to */
2047 static unsigned long mcount; /* # bytes to affect */
2048 static unsigned long mdiffs; /* max # differences to print */
2053 scanhex((void *)&mdest);
2054 if( termch != '\n' )
2056 scanhex((void *)(cmd == 's'? &mval: &msrc));
2057 if( termch != '\n' )
2059 scanhex((void *)&mcount);
2062 memmove((void *)mdest, (void *)msrc, mcount);
2065 memset((void *)mdest, mval, mcount);
2068 if( termch != '\n' )
2070 scanhex((void *)&mdiffs);
2071 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2077 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2082 for( n = nb; n > 0; --n )
2083 if( *p1++ != *p2++ )
2084 if( ++prt <= maxpr )
2085 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2086 p1[-1], p2 - 1, p2[-1]);
2088 printf("Total of %d differences\n", prt);
2091 static unsigned mend;
2092 static unsigned mask;
2098 unsigned char val[4];
2101 scanhex((void *)&mdest);
2102 if (termch != '\n') {
2104 scanhex((void *)&mend);
2105 if (termch != '\n') {
2107 scanhex((void *)&mval);
2109 if (termch != '\n') termch = 0;
2110 scanhex((void *)&mask);
2114 for (a = mdest; a < mend; a += 4) {
2115 if (mread(a, val, 4) == 4
2116 && ((GETWORD(val) ^ mval) & mask) == 0) {
2117 printf("%.16x: %.16x\n", a, GETWORD(val));
2124 static unsigned long mskip = 0x1000;
2125 static unsigned long mlim = 0xffffffff;
2135 if (termch != '\n') termch = 0;
2137 if (termch != '\n') termch = 0;
2140 for (a = mdest; a < mlim; a += mskip) {
2141 ok = mread(a, &v, 1);
2143 printf("%.8x .. ", a);
2145 } else if (!ok && ook)
2146 printf("%.8x\n", a - mskip);
2152 printf("%.8x\n", a - mskip);
2155 /* Input scanning routines */
2166 while( c == ' ' || c == '\t' )
2172 static char *regnames[N_PTREGS] = {
2173 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2174 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2175 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2176 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2177 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", "softe",
2178 "trap", "dar", "dsisr", "res"
2182 scanhex(unsigned long *vp)
2189 /* parse register name */
2193 for (i = 0; i < sizeof(regname) - 1; ++i) {
2202 for (i = 0; i < N_PTREGS; ++i) {
2203 if (strcmp(regnames[i], regname) == 0) {
2204 if (xmon_regs == NULL) {
2205 printf("regs not available\n");
2208 *vp = ((unsigned long *)xmon_regs)[i];
2212 printf("invalid register name '%%%s'\n", regname);
2216 /* skip leading "0x" if any */
2230 } else if (c == '$') {
2232 for (i=0; i<63; i++) {
2242 if (setjmp(bus_error_jmp) == 0) {
2243 catch_memory_errors = 1;
2245 *vp = kallsyms_lookup_name(tmpstr);
2248 catch_memory_errors = 0;
2250 printf("unknown symbol '%s'\n", tmpstr);
2286 if( '0' <= c && c <= '9' )
2288 if( 'A' <= c && c <= 'F' )
2289 return c - ('A' - 10);
2290 if( 'a' <= c && c <= 'f' )
2291 return c - ('a' - 10);
2296 getstring(char *s, int size)
2307 } while( c != ' ' && c != '\t' && c != '\n' );
2312 static char line[256];
2313 static char *lineptr;
2324 if (lineptr == NULL || *lineptr == 0) {
2325 if (fgets(line, sizeof(line), stdin) == NULL) {
2335 take_input(char *str)
2344 int type = inchar();
2346 static char tmp[64];
2351 xmon_print_symbol(addr, ": ", "\n");
2356 if (setjmp(bus_error_jmp) == 0) {
2357 catch_memory_errors = 1;
2359 addr = kallsyms_lookup_name(tmp);
2361 printf("%s: %lx\n", tmp, addr);
2363 printf("Symbol '%s' not found.\n", tmp);
2366 catch_memory_errors = 0;
2373 /* Print an address in numeric and symbolic form (if possible) */
2374 static void xmon_print_symbol(unsigned long address, const char *mid,
2378 const char *name = NULL;
2379 unsigned long offset, size;
2381 printf("%.16lx", address);
2382 if (setjmp(bus_error_jmp) == 0) {
2383 catch_memory_errors = 1;
2385 name = kallsyms_lookup(address, &size, &offset, &modname,
2388 /* wait a little while to see if we get a machine check */
2392 catch_memory_errors = 0;
2395 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2397 printf(" [%s]", modname);
2399 printf("%s", after);
2402 static void debug_trace(void)
2404 unsigned long val, cmd, on;
2408 /* show current state */
2410 printf("ppc64_debug_switch = 0x%lx\n", ppc64_debug_switch);
2411 for (i = 0; i < PPCDBG_NUM_FLAGS ;i++) {
2412 on = PPCDBG_BITVAL(i) & ppc64_debug_switch;
2413 printf("%02x %s %12s ", i, on ? "on " : "off", trace_names[i] ? trace_names[i] : "");
2414 if (((i+1) % 3) == 0)
2420 while (cmd != '\n') {
2421 on = 1; /* default if no sign given */
2422 while (cmd == '+' || cmd == '-') {
2425 if (cmd == ' ' || cmd == '\n') { /* Turn on or off based on + or - */
2426 ppc64_debug_switch = on ? PPCDBG_ALL:PPCDBG_NONE;
2427 printf("Setting all values to %s...\n", on ? "on" : "off");
2428 if (cmd == '\n') return;
2429 else cmd = skipbl();
2434 termch = cmd; /* not +/- ... let scanhex see it */
2435 scanhex((void *)&val);
2437 printf("Value %x out of range:\n", val);
2441 ppc64_debug_switch |= PPCDBG_BITVAL(val);
2442 printf("enable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
2444 ppc64_debug_switch &= ~PPCDBG_BITVAL(val);
2445 printf("disable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
2451 static void dump_slb(void)
2456 printf("SLB contents of cpu %x\n", smp_processor_id());
2458 for (i = 0; i < SLB_NUM_ENTRIES; i++) {
2459 asm volatile("slbmfee %0,%1" : "=r" (tmp) : "r" (i));
2460 printf("%02d %016lx ", i, tmp);
2462 asm volatile("slbmfev %0,%1" : "=r" (tmp) : "r" (i));
2463 printf("%016lx\n", tmp);
2467 static void dump_stab(void)
2470 unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2472 printf("Segment table contents of cpu %x\n", smp_processor_id());
2474 for (i = 0; i < PAGE_SIZE/16; i++) {
2481 printf("%03d %016lx ", i, a);
2482 printf("%016lx\n", b);
2487 void xmon_init(int enable)
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 __debugger_ipi = NULL;
2500 __debugger_bpt = NULL;
2501 __debugger_sstep = NULL;
2502 __debugger_iabr_match = NULL;
2503 __debugger_dabr_match = NULL;
2504 __debugger_fault_handler = NULL;
2508 void dump_segments(void)
2510 if (cpu_has_feature(CPU_FTR_SLB))