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>
31 #include <asm/ppcdebug.h>
32 #include <asm/cputable.h>
34 #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 static unsigned long ndump = 64;
54 static unsigned long nidump = 16;
55 static unsigned long ncsum = 4096;
57 static char tmpstr[128];
59 #define JMP_BUF_LEN (184/sizeof(long))
60 static long bus_error_jmp[JMP_BUF_LEN];
61 static int catch_memory_errors;
62 static long *xmon_fault_jmp[NR_CPUS];
63 #define setjmp xmon_setjmp
64 #define longjmp xmon_longjmp
66 /* Breakpoint stuff */
68 unsigned long address;
69 unsigned int instr[2];
75 /* Bits in bpt.enabled */
76 #define BP_IABR_TE 1 /* IABR translation enabled */
82 static struct bpt bpts[NBPTS];
83 static struct bpt dabr;
84 static struct bpt *iabr;
85 static unsigned bpinstr = 0x7fe00008; /* trap */
87 #define BP_NUM(bp) ((bp) - bpts + 1)
90 static int cmds(struct pt_regs *);
91 static int mread(unsigned long, void *, int);
92 static int mwrite(unsigned long, void *, int);
93 static int handle_fault(struct pt_regs *);
94 static void byterev(unsigned char *, int);
95 static void memex(void);
96 static int bsesc(void);
97 static void dump(void);
98 static void prdump(unsigned long, long);
99 static int ppc_inst_dump(unsigned long, long, int);
100 void print_address(unsigned long);
101 static void backtrace(struct pt_regs *);
102 static void excprint(struct pt_regs *);
103 static void prregs(struct pt_regs *);
104 static void memops(int);
105 static void memlocate(void);
106 static void memzcan(void);
107 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
109 int scanhex(unsigned long *valp);
110 static void scannl(void);
111 static int hexdigit(int);
112 void getstring(char *, int);
113 static void flush_input(void);
114 static int inchar(void);
115 static void take_input(char *);
116 static unsigned long read_spr(int);
117 static void write_spr(int, unsigned long);
118 static void super_regs(void);
119 static void remove_bpts(void);
120 static void insert_bpts(void);
121 static void remove_cpu_bpts(void);
122 static void insert_cpu_bpts(void);
123 static struct bpt *at_breakpoint(unsigned long pc);
124 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
125 static int do_step(struct pt_regs *);
126 static void bpt_cmds(void);
127 static void cacheflush(void);
128 static int cpu_cmd(void);
129 static void csum(void);
130 static void bootcmds(void);
131 void dump_segments(void);
132 static void symbol_lookup(void);
133 static void xmon_print_symbol(unsigned long address, const char *mid,
135 static const char *getvecname(unsigned long vec);
137 static void debug_trace(void);
139 extern int print_insn_powerpc(unsigned long, unsigned long, int);
140 extern void printf(const char *fmt, ...);
141 extern void xmon_vfprintf(void *f, const char *fmt, va_list ap);
142 extern int xmon_putc(int c, void *f);
143 extern int putchar(int ch);
144 extern int xmon_read_poll(void);
145 extern int setjmp(long *);
146 extern void longjmp(long *, int);
147 extern unsigned long _ASR;
149 pte_t *find_linux_pte(pgd_t *pgdir, unsigned long va); /* from htab.c */
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 * We don't allow single-stepping an mtmsrd that would clear
233 * MSR_RI, since that would make the exception unrecoverable.
234 * Since we need to single-step to proceed from a breakpoint,
235 * we don't allow putting a breakpoint on an mtmsrd instruction.
236 * Similarly we don't allow breakpoints on rfid instructions.
237 * These macros tell us if an instruction is a mtmsrd or rfid.
239 #define IS_MTMSRD(instr) (((instr) & 0xfc0007fe) == 0x7c000164)
240 #define IS_RFID(instr) (((instr) & 0xfc0007fe) == 0x4c000024)
243 * Disable surveillance (the service processor watchdog function)
244 * while we are in xmon.
245 * XXX we should re-enable it when we leave. :)
247 #define SURVEILLANCE_TOKEN 9000
249 static inline void disable_surveillance(void)
251 #ifdef CONFIG_PPC_PSERIES
252 /* Since this can't be a module, args should end up below 4GB. */
253 static struct rtas_args args;
256 * At this point we have got all the cpus we can into
257 * xmon, so there is hopefully no other cpu calling RTAS
258 * at the moment, even though we don't take rtas.lock.
259 * If we did try to take rtas.lock there would be a
260 * real possibility of deadlock.
262 args.token = rtas_token("set-indicator");
263 if (args.token == RTAS_UNKNOWN_SERVICE)
267 args.rets = &args.args[3];
268 args.args[0] = SURVEILLANCE_TOKEN;
271 enter_rtas(__pa(&args));
272 #endif /* CONFIG_PPC_PSERIES */
276 static int xmon_speaker;
278 static void get_output_lock(void)
280 int me = smp_processor_id() + 0x100;
281 int last_speaker = 0, prev;
284 if (xmon_speaker == me)
287 if (xmon_speaker == 0) {
288 last_speaker = cmpxchg(&xmon_speaker, 0, me);
289 if (last_speaker == 0)
293 while (xmon_speaker == last_speaker) {
296 /* hostile takeover */
297 prev = cmpxchg(&xmon_speaker, last_speaker, me);
298 if (prev == last_speaker)
305 static void release_output_lock(void)
311 int xmon_core(struct pt_regs *regs, int fromipi)
316 long recurse_jmp[JMP_BUF_LEN];
317 unsigned long offset;
321 unsigned long timeout;
325 set_msrd(msr & ~MSR_EE); /* disable interrupts */
327 bp = in_breakpoint_table(regs->nip, &offset);
329 regs->nip = bp->address + offset;
330 atomic_dec(&bp->ref_count);
336 cpu = smp_processor_id();
337 if (cpu_isset(cpu, cpus_in_xmon)) {
340 printf("cpu 0x%x: Exception %lx %s in xmon, "
341 "returning to main loop\n",
342 cpu, regs->trap, getvecname(TRAP(regs)));
343 longjmp(xmon_fault_jmp[cpu], 1);
346 if (setjmp(recurse_jmp) != 0) {
347 if (!in_xmon || !xmon_gate) {
348 printf("xmon: WARNING: bad recursive fault "
349 "on cpu 0x%x\n", cpu);
352 secondary = !(xmon_taken && cpu == xmon_owner);
356 xmon_fault_jmp[cpu] = recurse_jmp;
357 cpu_set(cpu, cpus_in_xmon);
360 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
361 bp = at_breakpoint(regs->nip);
362 if (bp || (regs->msr & MSR_RI) == 0)
369 printf("cpu 0x%x stopped at breakpoint 0x%x (",
371 xmon_print_symbol(regs->nip, " ", ")\n");
373 if ((regs->msr & MSR_RI) == 0)
374 printf("WARNING: exception is not recoverable, "
376 release_output_lock();
381 while (secondary && !xmon_gate) {
385 secondary = test_and_set_bit(0, &in_xmon);
390 if (!secondary && !xmon_gate) {
391 /* we are the first cpu to come in */
392 /* interrupt other cpu(s) */
393 int ncpus = num_online_cpus();
398 smp_send_debugger_break(MSG_ALL_BUT_SELF);
399 /* wait for other cpus to come in */
400 for (timeout = 100000000; timeout != 0; --timeout) {
401 if (cpus_weight(cpus_in_xmon) >= ncpus)
407 disable_surveillance();
408 /* for breakpoint or single step, print the current instr. */
409 if (bp || TRAP(regs) == 0xd00)
410 ppc_inst_dump(regs->nip, 1, 0);
411 printf("enter ? for help\n");
420 if (cpu == xmon_owner) {
421 if (!test_and_set_bit(0, &xmon_taken)) {
426 while (cpu == xmon_owner)
440 /* have switched to some other cpu */
445 cpu_clear(cpu, cpus_in_xmon);
446 xmon_fault_jmp[cpu] = NULL;
449 /* UP is simple... */
451 printf("Exception %lx %s in xmon, returning to main loop\n",
452 regs->trap, getvecname(TRAP(regs)));
453 longjmp(xmon_fault_jmp[0], 1);
455 if (setjmp(recurse_jmp) == 0) {
456 xmon_fault_jmp[0] = recurse_jmp;
460 bp = at_breakpoint(regs->nip);
462 printf("Stopped at breakpoint %x (", BP_NUM(bp));
463 xmon_print_symbol(regs->nip, " ", ")\n");
465 if ((regs->msr & MSR_RI) == 0)
466 printf("WARNING: exception is not recoverable, "
469 disable_surveillance();
470 /* for breakpoint or single step, print the current instr. */
471 if (bp || TRAP(regs) == 0xd00)
472 ppc_inst_dump(regs->nip, 1, 0);
473 printf("enter ? for help\n");
482 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
483 bp = at_breakpoint(regs->nip);
485 int stepped = emulate_step(regs, bp->instr[0]);
487 regs->nip = (unsigned long) &bp->instr[0];
488 atomic_inc(&bp->ref_count);
489 } else if (stepped < 0) {
490 printf("Couldn't single-step %s instruction\n",
491 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
498 set_msrd(msr); /* restore interrupt enable */
503 int xmon(struct pt_regs *excp)
508 /* Ok, grab regs as they are now.
509 This won't do a particularily good job because the
510 prologue has already been executed.
511 ToDo: We could reach back into the callers save
512 area to do a better job of representing the
515 asm volatile ("std 0,0(%0)\n\
546 std 31,248(%0)" : : "b" (®s));
548 regs.nip = regs.link = ((unsigned long *)(regs.gpr[1]))[2];
549 regs.msr = get_msr();
550 regs.ctr = get_ctr();
551 regs.xer = get_xer();
556 return xmon_core(excp, 0);
559 int xmon_bpt(struct pt_regs *regs)
562 unsigned long offset;
564 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
567 /* Are we at the trap at bp->instr[1] for some bp? */
568 bp = in_breakpoint_table(regs->nip, &offset);
569 if (bp != NULL && offset == 4) {
570 regs->nip = bp->address + 4;
571 atomic_dec(&bp->ref_count);
575 /* Are we at a breakpoint? */
576 bp = at_breakpoint(regs->nip);
585 int xmon_sstep(struct pt_regs *regs)
593 int xmon_dabr_match(struct pt_regs *regs)
595 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
601 int xmon_iabr_match(struct pt_regs *regs)
603 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
611 int xmon_ipi(struct pt_regs *regs)
614 if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
620 int xmon_fault_handler(struct pt_regs *regs)
623 unsigned long offset;
625 if (in_xmon && catch_memory_errors)
626 handle_fault(regs); /* doesn't return */
628 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
629 bp = in_breakpoint_table(regs->nip, &offset);
631 regs->nip = bp->address + offset;
632 atomic_dec(&bp->ref_count);
640 static struct bpt *at_breakpoint(unsigned long pc)
646 for (i = 0; i < NBPTS; ++i, ++bp)
647 if (bp->enabled && pc == bp->address)
652 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
656 off = nip - (unsigned long) bpts;
657 if (off >= sizeof(bpts))
659 off %= sizeof(struct bpt);
660 if (off != offsetof(struct bpt, instr[0])
661 && off != offsetof(struct bpt, instr[1]))
663 *offp = off - offsetof(struct bpt, instr[0]);
664 return (struct bpt *) (nip - off);
667 static struct bpt *new_breakpoint(unsigned long a)
672 bp = at_breakpoint(a);
676 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
677 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
679 bp->instr[1] = bpinstr;
680 store_inst(&bp->instr[1]);
685 printf("Sorry, no free breakpoints. Please clear one first.\n");
689 static void insert_bpts(void)
695 for (i = 0; i < NBPTS; ++i, ++bp) {
696 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
698 if (mread(bp->address, &bp->instr[0], 4) != 4) {
699 printf("Couldn't read instruction at %lx, "
700 "disabling breakpoint there\n", bp->address);
704 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
705 printf("Breakpoint at %lx is on an mtmsrd or rfid "
706 "instruction, disabling it\n", bp->address);
710 store_inst(&bp->instr[0]);
711 if (bp->enabled & BP_IABR)
713 if (mwrite(bp->address, &bpinstr, 4) != 4) {
714 printf("Couldn't write instruction at %lx, "
715 "disabling breakpoint there\n", bp->address);
716 bp->enabled &= ~BP_TRAP;
719 store_inst((void *)bp->address);
723 static void insert_cpu_bpts(void)
726 set_dabr(dabr.address | (dabr.enabled & 7));
727 if (iabr && (cur_cpu_spec->cpu_features & CPU_FTR_IABR))
728 set_iabr(iabr->address
729 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
732 static void remove_bpts(void)
739 for (i = 0; i < NBPTS; ++i, ++bp) {
740 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
742 if (mread(bp->address, &instr, 4) == 4
744 && mwrite(bp->address, &bp->instr, 4) != 4)
745 printf("Couldn't remove breakpoint at %lx\n",
748 store_inst((void *)bp->address);
752 static void remove_cpu_bpts(void)
755 if ((cur_cpu_spec->cpu_features & CPU_FTR_IABR))
759 /* Command interpreting routine */
760 static char *last_cmd;
763 cmds(struct pt_regs *excp)
771 printf("%x:", smp_processor_id());
772 #endif /* CONFIG_SMP */
779 if (last_cmd == NULL)
781 take_input(last_cmd);
815 prregs(excp); /* print regs */
863 printf("Unrecognized command: ");
865 if (' ' < cmd && cmd <= '~')
868 printf("\\x%x", cmd);
870 } while (cmd != '\n');
871 printf(" (type ? for help)\n");
878 * Step a single instruction.
879 * Some instructions we emulate, others we execute with MSR_SE set.
881 static int do_step(struct pt_regs *regs)
886 /* check we are in 64-bit kernel mode, translation enabled */
887 if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
888 if (mread(regs->nip, &instr, 4) == 4) {
889 stepped = emulate_step(regs, instr);
891 printf("Couldn't single-step %s instruction\n",
892 (IS_RFID(instr)? "rfid": "mtmsrd"));
896 regs->trap = 0xd00 | (regs->trap & 1);
897 printf("stepped to ");
898 xmon_print_symbol(regs->nip, " ", "\n");
899 ppc_inst_dump(regs->nip, 1, 0);
908 static void bootcmds(void)
914 ppc_md.restart(NULL);
921 static int cpu_cmd(void)
928 if (!scanhex(&cpu)) {
929 /* print cpus waiting or in xmon */
930 printf("cpus stopped:");
932 for (cpu = 0; cpu < NR_CPUS; ++cpu) {
933 if (cpu_isset(cpu, cpus_in_xmon)) {
939 printf("-%x", cpu - 1);
944 printf("-%x", NR_CPUS - 1);
948 /* try to switch to cpu specified */
949 if (!cpu_isset(cpu, cpus_in_xmon)) {
950 printf("cpu 0x%x isn't in xmon\n", cpu);
957 while (!xmon_taken) {
958 if (--timeout == 0) {
959 if (test_and_set_bit(0, &xmon_taken))
961 /* take control back */
963 xmon_owner = smp_processor_id();
964 printf("cpu %u didn't take control\n", cpu);
972 #endif /* CONFIG_SMP */
975 static unsigned short fcstab[256] = {
976 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
977 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
978 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
979 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
980 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
981 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
982 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
983 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
984 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
985 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
986 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
987 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
988 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
989 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
990 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
991 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
992 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
993 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
994 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
995 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
996 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
997 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
998 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
999 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1000 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1001 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1002 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1003 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1004 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1005 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1006 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1007 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1010 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1019 if (!scanhex(&adrs))
1021 if (!scanhex(&ncsum))
1024 for (i = 0; i < ncsum; ++i) {
1025 if (mread(adrs+i, &v, 1) == 0) {
1026 printf("csum stopped at %x\n", adrs+i);
1031 printf("%x\n", fcs);
1035 * Check if this is a suitable place to put a breakpoint.
1037 static long check_bp_loc(unsigned long addr)
1042 if (addr < KERNELBASE) {
1043 printf("Breakpoints may only be placed at kernel addresses\n");
1046 if (!mread(addr, &instr, sizeof(instr))) {
1047 printf("Can't read instruction at address %lx\n", addr);
1050 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1051 printf("Breakpoints may not be placed on mtmsrd or rfid "
1058 static char *breakpoint_help_string =
1059 "Breakpoint command usage:\n"
1060 "b show breakpoints\n"
1061 "b <addr> [cnt] set breakpoint at given instr addr\n"
1062 "bc clear all breakpoints\n"
1063 "bc <n/addr> clear breakpoint number n or at addr\n"
1064 "bi <addr> [cnt] set hardware instr breakpoint (broken?)\n"
1065 "bd <addr> [cnt] set hardware data breakpoint (broken?)\n"
1075 const char badaddr[] = "Only kernel addresses are permitted "
1076 "for breakpoints\n";
1080 case 'd': /* bd - hardware data breakpoint */
1085 else if (cmd == 'w')
1091 if (scanhex(&dabr.address)) {
1092 if (dabr.address < KERNELBASE) {
1097 dabr.enabled = mode | BP_DABR;
1101 case 'i': /* bi - hardware instr breakpoint */
1102 if (!(cur_cpu_spec->cpu_features & CPU_FTR_IABR)) {
1103 printf("Hardware instruction breakpoint "
1104 "not supported on this cpu\n");
1108 iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1113 if (!check_bp_loc(a))
1115 bp = new_breakpoint(a);
1117 bp->enabled |= BP_IABR | BP_IABR_TE;
1124 /* clear all breakpoints */
1125 for (i = 0; i < NBPTS; ++i)
1126 bpts[i].enabled = 0;
1129 printf("All breakpoints cleared\n");
1133 if (a <= NBPTS && a >= 1) {
1134 /* assume a breakpoint number */
1135 bp = &bpts[a-1]; /* bp nums are 1 based */
1137 /* assume a breakpoint address */
1138 bp = at_breakpoint(a);
1140 printf("No breakpoint at %x\n", a);
1145 printf("Cleared breakpoint %x (", BP_NUM(bp));
1146 xmon_print_symbol(bp->address, " ", ")\n");
1154 printf(breakpoint_help_string);
1159 /* print all breakpoints */
1160 printf(" type address\n");
1162 printf(" data %.16lx [", dabr.address);
1163 if (dabr.enabled & 1)
1165 if (dabr.enabled & 2)
1169 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1172 printf("%2x %s ", BP_NUM(bp),
1173 (bp->enabled & BP_IABR)? "inst": "trap");
1174 xmon_print_symbol(bp->address, " ", "\n");
1179 if (!check_bp_loc(a))
1181 bp = new_breakpoint(a);
1183 bp->enabled |= BP_TRAP;
1188 /* Very cheap human name for vector lookup. */
1190 const char *getvecname(unsigned long vec)
1195 case 0x100: ret = "(System Reset)"; break;
1196 case 0x200: ret = "(Machine Check)"; break;
1197 case 0x300: ret = "(Data Access)"; break;
1198 case 0x380: ret = "(Data SLB Access)"; break;
1199 case 0x400: ret = "(Instruction Access)"; break;
1200 case 0x480: ret = "(Instruction SLB Access)"; break;
1201 case 0x500: ret = "(Hardware Interrupt)"; break;
1202 case 0x600: ret = "(Alignment)"; break;
1203 case 0x700: ret = "(Program Check)"; break;
1204 case 0x800: ret = "(FPU Unavailable)"; break;
1205 case 0x900: ret = "(Decrementer)"; break;
1206 case 0xc00: ret = "(System Call)"; break;
1207 case 0xd00: ret = "(Single Step)"; break;
1208 case 0xf00: ret = "(Performance Monitor)"; break;
1209 case 0xf20: ret = "(Altivec Unavailable)"; break;
1210 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1216 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1217 unsigned long *endp)
1219 unsigned long size, offset;
1223 *startp = *endp = 0;
1226 if (setjmp(bus_error_jmp) == 0) {
1227 catch_memory_errors = 1;
1229 name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr);
1231 *startp = pc - offset;
1232 *endp = pc - offset + size;
1236 catch_memory_errors = 0;
1239 static int xmon_depth_to_print = 64;
1241 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1245 unsigned long newsp;
1246 unsigned long marker;
1248 struct pt_regs regs;
1251 if (sp < PAGE_OFFSET) {
1253 printf("SP (%lx) is in userspace\n", sp);
1257 if (!mread(sp + 16, &ip, sizeof(unsigned long))
1258 || !mread(sp, &newsp, sizeof(unsigned long))) {
1259 printf("Couldn't read stack frame at %lx\n", sp);
1264 * For the first stack frame, try to work out if
1265 * LR and/or the saved LR value in the bottommost
1266 * stack frame are valid.
1268 if ((pc | lr) != 0) {
1269 unsigned long fnstart, fnend;
1270 unsigned long nextip;
1273 get_function_bounds(pc, &fnstart, &fnend);
1276 mread(newsp + 16, &nextip,
1277 sizeof(unsigned long));
1279 if (lr < PAGE_OFFSET
1280 || (fnstart <= lr && lr < fnend))
1282 } else if (lr == nextip) {
1284 } else if (lr >= PAGE_OFFSET
1285 && !(fnstart <= lr && lr < fnend)) {
1286 printf("[link register ] ");
1287 xmon_print_symbol(lr, " ", "\n");
1290 printf("[%.16lx] ", sp);
1291 xmon_print_symbol(ip, " ", " (unreliable)\n");
1296 printf("[%.16lx] ", sp);
1297 xmon_print_symbol(ip, " ", "\n");
1300 /* Look for "regshere" marker to see if this is
1301 an exception frame. */
1302 if (mread(sp + 0x60, &marker, sizeof(unsigned long))
1303 && marker == 0x7265677368657265ul) {
1304 if (mread(sp + 0x70, ®s, sizeof(regs))
1306 printf("Couldn't read registers at %lx\n",
1310 printf("--- Exception: %lx %s at ", regs.trap,
1311 getvecname(TRAP(®s)));
1314 xmon_print_symbol(pc, " ", "\n");
1321 } while (count++ < xmon_depth_to_print);
1324 static void backtrace(struct pt_regs *excp)
1329 xmon_show_stack(sp, 0, 0);
1331 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1335 void excprint(struct pt_regs *fp)
1340 printf("cpu 0x%x: ", smp_processor_id());
1341 #endif /* CONFIG_SMP */
1344 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1346 xmon_print_symbol(fp->nip, ": ", "\n");
1348 printf(" lr: ", fp->link);
1349 xmon_print_symbol(fp->link, ": ", "\n");
1351 printf(" sp: %lx\n", fp->gpr[1]);
1352 printf(" msr: %lx\n", fp->msr);
1354 if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1355 printf(" dar: %lx\n", fp->dar);
1357 printf(" dsisr: %lx\n", fp->dsisr);
1360 printf(" current = 0x%lx\n", current);
1361 printf(" paca = 0x%lx\n", get_paca());
1363 printf(" pid = %ld, comm = %s\n",
1364 current->pid, current->comm);
1368 void prregs(struct pt_regs *fp)
1372 struct pt_regs regs;
1374 if (scanhex(&base)) {
1375 if (setjmp(bus_error_jmp) == 0) {
1376 catch_memory_errors = 1;
1378 regs = *(struct pt_regs *)base;
1382 catch_memory_errors = 0;
1383 printf("*** Error reading registers from %.16lx\n",
1387 catch_memory_errors = 0;
1391 if (FULL_REGS(fp)) {
1392 for (n = 0; n < 16; ++n)
1393 printf("R%.2ld = %.16lx R%.2ld = %.16lx\n",
1394 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1396 for (n = 0; n < 7; ++n)
1397 printf("R%.2ld = %.16lx R%.2ld = %.16lx\n",
1398 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1401 xmon_print_symbol(fp->nip, " ", "\n");
1403 xmon_print_symbol(fp->link, " ", "\n");
1404 printf("msr = %.16lx cr = %.8lx\n", fp->msr, fp->ccr);
1405 printf("ctr = %.16lx xer = %.16lx trap = %8lx\n",
1406 fp->ctr, fp->xer, fp->trap);
1409 void cacheflush(void)
1412 unsigned long nflush;
1417 scanhex((void *)&adrs);
1422 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1423 if (setjmp(bus_error_jmp) == 0) {
1424 catch_memory_errors = 1;
1428 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1429 cflush((void *) adrs);
1431 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1432 cinval((void *) adrs);
1435 /* wait a little while to see if we get a machine check */
1438 catch_memory_errors = 0;
1444 unsigned int instrs[2];
1445 unsigned long (*code)(void);
1446 unsigned long opd[3];
1447 unsigned long ret = -1UL;
1449 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1450 instrs[1] = 0x4e800020;
1451 opd[0] = (unsigned long)instrs;
1455 store_inst(instrs+1);
1456 code = (unsigned long (*)(void)) opd;
1464 write_spr(int n, unsigned long val)
1466 unsigned int instrs[2];
1467 unsigned long (*code)(unsigned long);
1468 unsigned long opd[3];
1470 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1471 instrs[1] = 0x4e800020;
1472 opd[0] = (unsigned long)instrs;
1476 store_inst(instrs+1);
1477 code = (unsigned long (*)(unsigned long)) opd;
1482 static unsigned long regno;
1483 extern char exc_prolog;
1484 extern char dec_exc;
1491 #ifdef CONFIG_PPC_ISERIES
1492 struct paca_struct *ptrPaca = NULL;
1493 struct ItLpPaca *ptrLpPaca = NULL;
1494 struct ItLpRegSave *ptrLpRegSave = NULL;
1499 unsigned long sp, toc;
1500 asm("mr %0,1" : "=r" (sp) :);
1501 asm("mr %0,2" : "=r" (toc) :);
1503 printf("msr = %.16lx sprg0= %.16lx\n", get_msr(), get_sprg0());
1504 printf("pvr = %.16lx sprg1= %.16lx\n", get_pvr(), get_sprg1());
1505 printf("dec = %.16lx sprg2= %.16lx\n", get_dec(), get_sprg2());
1506 printf("sp = %.16lx sprg3= %.16lx\n", sp, get_sprg3());
1507 printf("toc = %.16lx dar = %.16lx\n", toc, get_dar());
1508 printf("srr0 = %.16lx srr1 = %.16lx\n", get_srr0(), get_srr1());
1509 #ifdef CONFIG_PPC_ISERIES
1510 // Dump out relevant Paca data areas.
1512 ptrPaca = get_paca();
1514 printf(" Local Processor Control Area (LpPaca): \n");
1515 ptrLpPaca = ptrPaca->lppaca_ptr;
1516 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1517 ptrLpPaca->xSavedSrr0, ptrLpPaca->xSavedSrr1);
1518 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1519 ptrLpPaca->xSavedGpr3, ptrLpPaca->xSavedGpr4);
1520 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->xSavedGpr5);
1522 printf(" Local Processor Register Save Area (LpRegSave): \n");
1523 ptrLpRegSave = ptrPaca->reg_save_ptr;
1524 printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n",
1525 ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
1526 printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n",
1527 ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
1528 printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n",
1529 ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
1538 val = read_spr(regno);
1540 write_spr(regno, val);
1543 printf("spr %lx = %lx\n", regno, read_spr(regno));
1555 * Stuff for reading and writing memory safely
1558 mread(unsigned long adrs, void *buf, int size)
1564 if (setjmp(bus_error_jmp) == 0) {
1565 catch_memory_errors = 1;
1571 *(short *)q = *(short *)p;
1574 *(int *)q = *(int *)p;
1577 *(long *)q = *(long *)p;
1580 for( ; n < size; ++n) {
1586 /* wait a little while to see if we get a machine check */
1590 catch_memory_errors = 0;
1595 mwrite(unsigned long adrs, void *buf, int size)
1601 if (setjmp(bus_error_jmp) == 0) {
1602 catch_memory_errors = 1;
1608 *(short *)p = *(short *)q;
1611 *(int *)p = *(int *)q;
1614 *(long *)p = *(long *)q;
1617 for ( ; n < size; ++n) {
1623 /* wait a little while to see if we get a machine check */
1627 printf("*** Error writing address %x\n", adrs + n);
1629 catch_memory_errors = 0;
1633 static int fault_type;
1634 static char *fault_chars[] = { "--", "**", "##" };
1637 handle_fault(struct pt_regs *regs)
1639 switch (TRAP(regs)) {
1651 longjmp(bus_error_jmp, 1);
1656 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1659 byterev(unsigned char *val, int size)
1665 SWAP(val[0], val[1], t);
1668 SWAP(val[0], val[3], t);
1669 SWAP(val[1], val[2], t);
1671 case 8: /* is there really any use for this? */
1672 SWAP(val[0], val[7], t);
1673 SWAP(val[1], val[6], t);
1674 SWAP(val[2], val[5], t);
1675 SWAP(val[3], val[4], t);
1683 static char *memex_help_string =
1684 "Memory examine command usage:\n"
1685 "m [addr] [flags] examine/change memory\n"
1686 " addr is optional. will start where left off.\n"
1687 " flags may include chars from this set:\n"
1688 " b modify by bytes (default)\n"
1689 " w modify by words (2 byte)\n"
1690 " l modify by longs (4 byte)\n"
1691 " d modify by doubleword (8 byte)\n"
1692 " r toggle reverse byte order mode\n"
1693 " n do not read memory (for i/o spaces)\n"
1694 " . ok to read (default)\n"
1695 "NOTE: flags are saved as defaults\n"
1698 static char *memex_subcmd_help_string =
1699 "Memory examine subcommands:\n"
1700 " hexval write this val to current location\n"
1701 " 'string' write chars from string to this location\n"
1702 " ' increment address\n"
1703 " ^ decrement address\n"
1704 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1705 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1706 " ` clear no-read flag\n"
1707 " ; stay at this addr\n"
1708 " v change to byte mode\n"
1709 " w change to word (2 byte) mode\n"
1710 " l change to long (4 byte) mode\n"
1711 " u change to doubleword (8 byte) mode\n"
1712 " m addr change current addr\n"
1713 " n toggle no-read flag\n"
1714 " r toggle byte reverse flag\n"
1715 " < count back up count bytes\n"
1716 " > count skip forward count bytes\n"
1717 " x exit this mode\n"
1723 int cmd, inc, i, nslash;
1725 unsigned char val[16];
1727 scanhex((void *)&adrs);
1730 printf(memex_help_string);
1736 while ((cmd = skipbl()) != '\n') {
1738 case 'b': size = 1; break;
1739 case 'w': size = 2; break;
1740 case 'l': size = 4; break;
1741 case 'd': size = 8; break;
1742 case 'r': brev = !brev; break;
1743 case 'n': mnoread = 1; break;
1744 case '.': mnoread = 0; break;
1753 n = mread(adrs, val, size);
1754 printf("%.16x%c", adrs, brev? 'r': ' ');
1759 for (i = 0; i < n; ++i)
1760 printf("%.2x", val[i]);
1761 for (; i < size; ++i)
1762 printf("%s", fault_chars[fault_type]);
1769 for (i = 0; i < size; ++i)
1770 val[i] = n >> (i * 8);
1773 mwrite(adrs, val, size);
1786 else if( n == '\'' )
1788 for (i = 0; i < size; ++i)
1789 val[i] = n >> (i * 8);
1792 mwrite(adrs, val, size);
1829 adrs -= 1 << nslash;
1833 adrs += 1 << nslash;
1837 adrs += 1 << -nslash;
1841 adrs -= 1 << -nslash;
1844 scanhex((void *)&adrs);
1863 printf(memex_subcmd_help_string);
1878 case 'n': c = '\n'; break;
1879 case 'r': c = '\r'; break;
1880 case 'b': c = '\b'; break;
1881 case 't': c = '\t'; break;
1886 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
1887 || ('a' <= (c) && (c) <= 'f') \
1888 || ('A' <= (c) && (c) <= 'F'))
1895 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
1897 scanhex((void *)&adrs);
1904 adrs += ppc_inst_dump(adrs, nidump, 1);
1910 prdump(adrs, ndump);
1917 prdump(unsigned long adrs, long ndump)
1919 long n, m, c, r, nr;
1920 unsigned char temp[16];
1922 for (n = ndump; n > 0;) {
1923 printf("%.16lx", adrs);
1926 nr = mread(adrs, temp, r);
1928 for (m = 0; m < r; ++m) {
1929 if ((m & 7) == 0 && m > 0)
1932 printf("%.2x", temp[m]);
1934 printf("%s", fault_chars[fault_type]);
1941 for (m = 0; m < r; ++m) {
1944 putchar(' ' <= c && c <= '~'? c: '.');
1958 ppc_inst_dump(unsigned long adr, long count, int praddr)
1961 unsigned long first_adr;
1962 unsigned long inst, last_inst = 0;
1963 unsigned char val[4];
1966 for (first_adr = adr; count > 0; --count, adr += 4) {
1967 nr = mread(adr, val, 4);
1970 const char *x = fault_chars[fault_type];
1971 printf("%.16lx %s%s%s%s\n", adr, x, x, x, x);
1975 inst = GETWORD(val);
1976 if (adr > first_adr && inst == last_inst) {
1986 printf("%.16lx %.8x", adr, inst);
1988 print_insn_powerpc(inst, adr, 0); /* always returns 4 */
1991 return adr - first_adr;
1995 print_address(unsigned long addr)
1997 xmon_print_symbol(addr, "\t# ", "");
2002 * Memory operations - move, set, print differences
2004 static unsigned long mdest; /* destination address */
2005 static unsigned long msrc; /* source address */
2006 static unsigned long mval; /* byte value to set memory to */
2007 static unsigned long mcount; /* # bytes to affect */
2008 static unsigned long mdiffs; /* max # differences to print */
2013 scanhex((void *)&mdest);
2014 if( termch != '\n' )
2016 scanhex((void *)(cmd == 's'? &mval: &msrc));
2017 if( termch != '\n' )
2019 scanhex((void *)&mcount);
2022 memmove((void *)mdest, (void *)msrc, mcount);
2025 memset((void *)mdest, mval, mcount);
2028 if( termch != '\n' )
2030 scanhex((void *)&mdiffs);
2031 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2037 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2042 for( n = nb; n > 0; --n )
2043 if( *p1++ != *p2++ )
2044 if( ++prt <= maxpr )
2045 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2046 p1[-1], p2 - 1, p2[-1]);
2048 printf("Total of %d differences\n", prt);
2051 static unsigned mend;
2052 static unsigned mask;
2058 unsigned char val[4];
2061 scanhex((void *)&mdest);
2062 if (termch != '\n') {
2064 scanhex((void *)&mend);
2065 if (termch != '\n') {
2067 scanhex((void *)&mval);
2069 if (termch != '\n') termch = 0;
2070 scanhex((void *)&mask);
2074 for (a = mdest; a < mend; a += 4) {
2075 if (mread(a, val, 4) == 4
2076 && ((GETWORD(val) ^ mval) & mask) == 0) {
2077 printf("%.16x: %.16x\n", a, GETWORD(val));
2084 static unsigned long mskip = 0x1000;
2085 static unsigned long mlim = 0xffffffff;
2095 if (termch != '\n') termch = 0;
2097 if (termch != '\n') termch = 0;
2100 for (a = mdest; a < mlim; a += mskip) {
2101 ok = mread(a, &v, 1);
2103 printf("%.8x .. ", a);
2105 } else if (!ok && ook)
2106 printf("%.8x\n", a - mskip);
2112 printf("%.8x\n", a - mskip);
2115 /* Input scanning routines */
2126 while( c == ' ' || c == '\t' )
2132 static char *regnames[N_PTREGS] = {
2133 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2134 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2135 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2136 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2137 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", "softe",
2138 "trap", "dar", "dsisr", "res"
2142 scanhex(unsigned long *vp)
2149 /* parse register name */
2153 for (i = 0; i < sizeof(regname) - 1; ++i) {
2162 for (i = 0; i < N_PTREGS; ++i) {
2163 if (strcmp(regnames[i], regname) == 0) {
2164 if (xmon_regs == NULL) {
2165 printf("regs not available\n");
2168 *vp = ((unsigned long *)xmon_regs)[i];
2172 printf("invalid register name '%%%s'\n", regname);
2176 /* skip leading "0x" if any */
2190 } else if (c == '$') {
2192 for (i=0; i<63; i++) {
2201 *vp = kallsyms_lookup_name(tmpstr);
2203 printf("unknown symbol '%s'\n", tmpstr);
2239 if( '0' <= c && c <= '9' )
2241 if( 'A' <= c && c <= 'F' )
2242 return c - ('A' - 10);
2243 if( 'a' <= c && c <= 'f' )
2244 return c - ('a' - 10);
2249 getstring(char *s, int size)
2260 } while( c != ' ' && c != '\t' && c != '\n' );
2265 static char line[256];
2266 static char *lineptr;
2277 if (lineptr == NULL || *lineptr == 0) {
2278 if (fgets(line, sizeof(line), stdin) == NULL) {
2288 take_input(char *str)
2297 int type = inchar();
2299 static char tmp[64];
2304 xmon_print_symbol(addr, ": ", "\n");
2309 if (setjmp(bus_error_jmp) == 0) {
2310 catch_memory_errors = 1;
2312 addr = kallsyms_lookup_name(tmp);
2314 printf("%s: %lx\n", tmp, addr);
2316 printf("Symbol '%s' not found.\n", tmp);
2319 catch_memory_errors = 0;
2326 /* Print an address in numeric and symbolic form (if possible) */
2327 static void xmon_print_symbol(unsigned long address, const char *mid,
2331 const char *name = NULL;
2332 unsigned long offset, size;
2334 printf("%.16lx", address);
2335 if (setjmp(bus_error_jmp) == 0) {
2336 catch_memory_errors = 1;
2338 name = kallsyms_lookup(address, &size, &offset, &modname,
2341 /* wait a little while to see if we get a machine check */
2345 catch_memory_errors = 0;
2348 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2350 printf(" [%s]", modname);
2352 printf("%s", after);
2355 static void debug_trace(void)
2357 unsigned long val, cmd, on;
2361 /* show current state */
2363 printf("naca->debug_switch = 0x%lx\n", naca->debug_switch);
2364 for (i = 0; i < PPCDBG_NUM_FLAGS ;i++) {
2365 on = PPCDBG_BITVAL(i) & naca->debug_switch;
2366 printf("%02x %s %12s ", i, on ? "on " : "off", trace_names[i] ? trace_names[i] : "");
2367 if (((i+1) % 3) == 0)
2373 while (cmd != '\n') {
2374 on = 1; /* default if no sign given */
2375 while (cmd == '+' || cmd == '-') {
2378 if (cmd == ' ' || cmd == '\n') { /* Turn on or off based on + or - */
2379 naca->debug_switch = on ? PPCDBG_ALL:PPCDBG_NONE;
2380 printf("Setting all values to %s...\n", on ? "on" : "off");
2381 if (cmd == '\n') return;
2382 else cmd = skipbl();
2387 termch = cmd; /* not +/- ... let scanhex see it */
2388 scanhex((void *)&val);
2390 printf("Value %x out of range:\n", val);
2394 naca->debug_switch |= PPCDBG_BITVAL(val);
2395 printf("enable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
2397 naca->debug_switch &= ~PPCDBG_BITVAL(val);
2398 printf("disable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
2404 static void dump_slb(void)
2409 printf("SLB contents of cpu %x\n", smp_processor_id());
2411 for (i = 0; i < SLB_NUM_ENTRIES; i++) {
2412 asm volatile("slbmfee %0,%1" : "=r" (tmp) : "r" (i));
2413 printf("%02d %016lx ", i, tmp);
2415 asm volatile("slbmfev %0,%1" : "=r" (tmp) : "r" (i));
2416 printf("%016lx\n", tmp);
2420 static void dump_stab(void)
2423 unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2425 printf("Segment table contents of cpu %x\n", smp_processor_id());
2427 for (i = 0; i < PAGE_SIZE/16; i++) {
2434 printf("%03d %016lx ", i, a);
2435 printf("%016lx\n", b);
2440 void xmon_init(void)
2443 __debugger_ipi = xmon_ipi;
2444 __debugger_bpt = xmon_bpt;
2445 __debugger_sstep = xmon_sstep;
2446 __debugger_iabr_match = xmon_iabr_match;
2447 __debugger_dabr_match = xmon_dabr_match;
2448 __debugger_fault_handler = xmon_fault_handler;
2451 void dump_segments(void)
2453 if (cur_cpu_spec->cpu_features & CPU_FTR_SLB)