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 longjmp(xmon_fault_jmp[cpu], 1);
335 if (setjmp(recurse_jmp) != 0) {
336 if (!in_xmon || !xmon_gate) {
337 printf("xmon: WARNING: bad recursive fault "
338 "on cpu 0x%x\n", cpu);
341 secondary = !(xmon_taken && cpu == xmon_owner);
345 xmon_fault_jmp[cpu] = recurse_jmp;
346 cpu_set(cpu, cpus_in_xmon);
349 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
350 bp = at_breakpoint(regs->nip);
351 if (bp || (regs->msr & MSR_RI) == 0)
358 printf("cpu 0x%x stopped at breakpoint 0x%x (",
360 xmon_print_symbol(regs->nip, " ", ")\n");
362 if ((regs->msr & MSR_RI) == 0)
363 printf("WARNING: exception is not recoverable, "
365 release_output_lock();
370 while (secondary && !xmon_gate) {
374 secondary = test_and_set_bit(0, &in_xmon);
379 if (!secondary && !xmon_gate) {
380 /* we are the first cpu to come in */
381 /* interrupt other cpu(s) */
382 int ncpus = num_online_cpus();
387 smp_send_debugger_break(MSG_ALL_BUT_SELF);
388 /* wait for other cpus to come in */
389 for (timeout = 100000000; timeout != 0; --timeout) {
390 if (cpus_weight(cpus_in_xmon) >= ncpus)
396 disable_surveillance();
397 /* for breakpoint or single step, print the current instr. */
398 if (bp || TRAP(regs) == 0xd00)
399 ppc_inst_dump(regs->nip, 1, 0);
400 printf("enter ? for help\n");
409 if (cpu == xmon_owner) {
410 if (!test_and_set_bit(0, &xmon_taken)) {
415 while (cpu == xmon_owner)
429 /* have switched to some other cpu */
434 cpu_clear(cpu, cpus_in_xmon);
435 xmon_fault_jmp[cpu] = NULL;
438 /* UP is simple... */
440 printf("Exception %lx %s in xmon, returning to main loop\n",
441 regs->trap, getvecname(TRAP(regs)));
442 longjmp(xmon_fault_jmp[0], 1);
444 if (setjmp(recurse_jmp) == 0) {
445 xmon_fault_jmp[0] = recurse_jmp;
449 bp = at_breakpoint(regs->nip);
451 printf("Stopped at breakpoint %x (", BP_NUM(bp));
452 xmon_print_symbol(regs->nip, " ", ")\n");
454 if ((regs->msr & MSR_RI) == 0)
455 printf("WARNING: exception is not recoverable, "
458 disable_surveillance();
459 /* for breakpoint or single step, print the current instr. */
460 if (bp || TRAP(regs) == 0xd00)
461 ppc_inst_dump(regs->nip, 1, 0);
462 printf("enter ? for help\n");
471 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
472 bp = at_breakpoint(regs->nip);
474 int stepped = emulate_step(regs, bp->instr[0]);
476 regs->nip = (unsigned long) &bp->instr[0];
477 atomic_inc(&bp->ref_count);
478 } else if (stepped < 0) {
479 printf("Couldn't single-step %s instruction\n",
480 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
487 set_msrd(msr); /* restore interrupt enable */
492 int xmon(struct pt_regs *excp)
497 /* Ok, grab regs as they are now.
498 This won't do a particularily good job because the
499 prologue has already been executed.
500 ToDo: We could reach back into the callers save
501 area to do a better job of representing the
504 asm volatile ("std 0,0(%0)\n\
535 std 31,248(%0)" : : "b" (®s));
537 regs.nip = regs.link = ((unsigned long *)(regs.gpr[1]))[2];
538 regs.msr = get_msr();
539 regs.ctr = get_ctr();
540 regs.xer = get_xer();
545 return xmon_core(excp, 0);
548 int xmon_bpt(struct pt_regs *regs)
551 unsigned long offset;
553 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
556 /* Are we at the trap at bp->instr[1] for some bp? */
557 bp = in_breakpoint_table(regs->nip, &offset);
558 if (bp != NULL && offset == 4) {
559 regs->nip = bp->address + 4;
560 atomic_dec(&bp->ref_count);
564 /* Are we at a breakpoint? */
565 bp = at_breakpoint(regs->nip);
574 int xmon_sstep(struct pt_regs *regs)
582 int xmon_dabr_match(struct pt_regs *regs)
584 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
590 int xmon_iabr_match(struct pt_regs *regs)
592 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
600 int xmon_ipi(struct pt_regs *regs)
603 if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
609 int xmon_fault_handler(struct pt_regs *regs)
612 unsigned long offset;
614 if (in_xmon && catch_memory_errors)
615 handle_fault(regs); /* doesn't return */
617 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
618 bp = in_breakpoint_table(regs->nip, &offset);
620 regs->nip = bp->address + offset;
621 atomic_dec(&bp->ref_count);
628 /* On systems with a hypervisor, we can't set the DABR
629 (data address breakpoint register) directly. */
630 static void set_controlled_dabr(unsigned long val)
632 #ifdef CONFIG_PPC_PSERIES
633 if (systemcfg->platform == PLATFORM_PSERIES_LPAR) {
634 int rc = plpar_hcall_norets(H_SET_DABR, val);
636 xmon_printf("Warning: setting DABR failed (%d)\n", rc);
642 static struct bpt *at_breakpoint(unsigned long pc)
648 for (i = 0; i < NBPTS; ++i, ++bp)
649 if (bp->enabled && pc == bp->address)
654 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
658 off = nip - (unsigned long) bpts;
659 if (off >= sizeof(bpts))
661 off %= sizeof(struct bpt);
662 if (off != offsetof(struct bpt, instr[0])
663 && off != offsetof(struct bpt, instr[1]))
665 *offp = off - offsetof(struct bpt, instr[0]);
666 return (struct bpt *) (nip - off);
669 static struct bpt *new_breakpoint(unsigned long a)
674 bp = at_breakpoint(a);
678 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
679 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
681 bp->instr[1] = bpinstr;
682 store_inst(&bp->instr[1]);
687 printf("Sorry, no free breakpoints. Please clear one first.\n");
691 static void insert_bpts(void)
697 for (i = 0; i < NBPTS; ++i, ++bp) {
698 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
700 if (mread(bp->address, &bp->instr[0], 4) != 4) {
701 printf("Couldn't read instruction at %lx, "
702 "disabling breakpoint there\n", bp->address);
706 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
707 printf("Breakpoint at %lx is on an mtmsrd or rfid "
708 "instruction, disabling it\n", bp->address);
712 store_inst(&bp->instr[0]);
713 if (bp->enabled & BP_IABR)
715 if (mwrite(bp->address, &bpinstr, 4) != 4) {
716 printf("Couldn't write instruction at %lx, "
717 "disabling breakpoint there\n", bp->address);
718 bp->enabled &= ~BP_TRAP;
721 store_inst((void *)bp->address);
725 static void insert_cpu_bpts(void)
728 set_controlled_dabr(dabr.address | (dabr.enabled & 7));
729 if (iabr && cpu_has_feature(CPU_FTR_IABR))
730 set_iabr(iabr->address
731 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
734 static void remove_bpts(void)
741 for (i = 0; i < NBPTS; ++i, ++bp) {
742 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
744 if (mread(bp->address, &instr, 4) == 4
746 && mwrite(bp->address, &bp->instr, 4) != 4)
747 printf("Couldn't remove breakpoint at %lx\n",
750 store_inst((void *)bp->address);
754 static void remove_cpu_bpts(void)
756 set_controlled_dabr(0);
757 if (cpu_has_feature(CPU_FTR_IABR))
761 /* Command interpreting routine */
762 static char *last_cmd;
765 cmds(struct pt_regs *excp)
773 printf("%x:", smp_processor_id());
774 #endif /* CONFIG_SMP */
781 if (last_cmd == NULL)
783 take_input(last_cmd);
817 prregs(excp); /* print regs */
865 printf("Unrecognized command: ");
867 if (' ' < cmd && cmd <= '~')
870 printf("\\x%x", cmd);
872 } while (cmd != '\n');
873 printf(" (type ? for help)\n");
880 * Step a single instruction.
881 * Some instructions we emulate, others we execute with MSR_SE set.
883 static int do_step(struct pt_regs *regs)
888 /* check we are in 64-bit kernel mode, translation enabled */
889 if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
890 if (mread(regs->nip, &instr, 4) == 4) {
891 stepped = emulate_step(regs, instr);
893 printf("Couldn't single-step %s instruction\n",
894 (IS_RFID(instr)? "rfid": "mtmsrd"));
898 regs->trap = 0xd00 | (regs->trap & 1);
899 printf("stepped to ");
900 xmon_print_symbol(regs->nip, " ", "\n");
901 ppc_inst_dump(regs->nip, 1, 0);
910 static void bootcmds(void)
916 ppc_md.restart(NULL);
923 static int cpu_cmd(void)
930 if (!scanhex(&cpu)) {
931 /* print cpus waiting or in xmon */
932 printf("cpus stopped:");
934 for (cpu = 0; cpu < NR_CPUS; ++cpu) {
935 if (cpu_isset(cpu, cpus_in_xmon)) {
941 printf("-%x", cpu - 1);
946 printf("-%x", NR_CPUS - 1);
950 /* try to switch to cpu specified */
951 if (!cpu_isset(cpu, cpus_in_xmon)) {
952 printf("cpu 0x%x isn't in xmon\n", cpu);
959 while (!xmon_taken) {
960 if (--timeout == 0) {
961 if (test_and_set_bit(0, &xmon_taken))
963 /* take control back */
965 xmon_owner = smp_processor_id();
966 printf("cpu %u didn't take control\n", cpu);
974 #endif /* CONFIG_SMP */
977 static unsigned short fcstab[256] = {
978 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
979 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
980 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
981 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
982 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
983 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
984 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
985 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
986 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
987 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
988 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
989 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
990 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
991 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
992 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
993 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
994 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
995 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
996 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
997 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
998 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
999 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1000 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1001 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1002 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1003 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1004 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1005 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1006 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1007 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1008 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1009 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1012 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1021 if (!scanhex(&adrs))
1023 if (!scanhex(&ncsum))
1026 for (i = 0; i < ncsum; ++i) {
1027 if (mread(adrs+i, &v, 1) == 0) {
1028 printf("csum stopped at %x\n", adrs+i);
1033 printf("%x\n", fcs);
1037 * Check if this is a suitable place to put a breakpoint.
1039 static long check_bp_loc(unsigned long addr)
1044 if (addr < KERNELBASE) {
1045 printf("Breakpoints may only be placed at kernel addresses\n");
1048 if (!mread(addr, &instr, sizeof(instr))) {
1049 printf("Can't read instruction at address %lx\n", addr);
1052 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1053 printf("Breakpoints may not be placed on mtmsrd or rfid "
1060 static char *breakpoint_help_string =
1061 "Breakpoint command usage:\n"
1062 "b show breakpoints\n"
1063 "b <addr> [cnt] set breakpoint at given instr addr\n"
1064 "bc clear all breakpoints\n"
1065 "bc <n/addr> clear breakpoint number n or at addr\n"
1066 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1067 "bd <addr> [cnt] set hardware data breakpoint\n"
1077 const char badaddr[] = "Only kernel addresses are permitted "
1078 "for breakpoints\n";
1082 case 'd': /* bd - hardware data breakpoint */
1087 else if (cmd == 'w')
1093 if (scanhex(&dabr.address)) {
1094 if (dabr.address < KERNELBASE) {
1099 dabr.enabled = mode | BP_DABR;
1103 case 'i': /* bi - hardware instr breakpoint */
1104 if (!cpu_has_feature(CPU_FTR_IABR)) {
1105 printf("Hardware instruction breakpoint "
1106 "not supported on this cpu\n");
1110 iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1115 if (!check_bp_loc(a))
1117 bp = new_breakpoint(a);
1119 bp->enabled |= BP_IABR | BP_IABR_TE;
1126 /* clear all breakpoints */
1127 for (i = 0; i < NBPTS; ++i)
1128 bpts[i].enabled = 0;
1131 printf("All breakpoints cleared\n");
1135 if (a <= NBPTS && a >= 1) {
1136 /* assume a breakpoint number */
1137 bp = &bpts[a-1]; /* bp nums are 1 based */
1139 /* assume a breakpoint address */
1140 bp = at_breakpoint(a);
1142 printf("No breakpoint at %x\n", a);
1147 printf("Cleared breakpoint %x (", BP_NUM(bp));
1148 xmon_print_symbol(bp->address, " ", ")\n");
1156 printf(breakpoint_help_string);
1161 /* print all breakpoints */
1162 printf(" type address\n");
1164 printf(" data %.16lx [", dabr.address);
1165 if (dabr.enabled & 1)
1167 if (dabr.enabled & 2)
1171 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1174 printf("%2x %s ", BP_NUM(bp),
1175 (bp->enabled & BP_IABR)? "inst": "trap");
1176 xmon_print_symbol(bp->address, " ", "\n");
1181 if (!check_bp_loc(a))
1183 bp = new_breakpoint(a);
1185 bp->enabled |= BP_TRAP;
1190 /* Very cheap human name for vector lookup. */
1192 const char *getvecname(unsigned long vec)
1197 case 0x100: ret = "(System Reset)"; break;
1198 case 0x200: ret = "(Machine Check)"; break;
1199 case 0x300: ret = "(Data Access)"; break;
1200 case 0x380: ret = "(Data SLB Access)"; break;
1201 case 0x400: ret = "(Instruction Access)"; break;
1202 case 0x480: ret = "(Instruction SLB Access)"; break;
1203 case 0x500: ret = "(Hardware Interrupt)"; break;
1204 case 0x600: ret = "(Alignment)"; break;
1205 case 0x700: ret = "(Program Check)"; break;
1206 case 0x800: ret = "(FPU Unavailable)"; break;
1207 case 0x900: ret = "(Decrementer)"; break;
1208 case 0xc00: ret = "(System Call)"; break;
1209 case 0xd00: ret = "(Single Step)"; break;
1210 case 0xf00: ret = "(Performance Monitor)"; break;
1211 case 0xf20: ret = "(Altivec Unavailable)"; break;
1212 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1218 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1219 unsigned long *endp)
1221 unsigned long size, offset;
1225 *startp = *endp = 0;
1228 if (setjmp(bus_error_jmp) == 0) {
1229 catch_memory_errors = 1;
1231 name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr);
1233 *startp = pc - offset;
1234 *endp = pc - offset + size;
1238 catch_memory_errors = 0;
1241 static int xmon_depth_to_print = 64;
1243 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1247 unsigned long newsp;
1248 unsigned long marker;
1250 struct pt_regs regs;
1253 if (sp < PAGE_OFFSET) {
1255 printf("SP (%lx) is in userspace\n", sp);
1259 if (!mread(sp + 16, &ip, sizeof(unsigned long))
1260 || !mread(sp, &newsp, sizeof(unsigned long))) {
1261 printf("Couldn't read stack frame at %lx\n", sp);
1266 * For the first stack frame, try to work out if
1267 * LR and/or the saved LR value in the bottommost
1268 * stack frame are valid.
1270 if ((pc | lr) != 0) {
1271 unsigned long fnstart, fnend;
1272 unsigned long nextip;
1275 get_function_bounds(pc, &fnstart, &fnend);
1278 mread(newsp + 16, &nextip,
1279 sizeof(unsigned long));
1281 if (lr < PAGE_OFFSET
1282 || (fnstart <= lr && lr < fnend))
1284 } else if (lr == nextip) {
1286 } else if (lr >= PAGE_OFFSET
1287 && !(fnstart <= lr && lr < fnend)) {
1288 printf("[link register ] ");
1289 xmon_print_symbol(lr, " ", "\n");
1292 printf("[%.16lx] ", sp);
1293 xmon_print_symbol(ip, " ", " (unreliable)\n");
1298 printf("[%.16lx] ", sp);
1299 xmon_print_symbol(ip, " ", "\n");
1302 /* Look for "regshere" marker to see if this is
1303 an exception frame. */
1304 if (mread(sp + 0x60, &marker, sizeof(unsigned long))
1305 && marker == 0x7265677368657265ul) {
1306 if (mread(sp + 0x70, ®s, sizeof(regs))
1308 printf("Couldn't read registers at %lx\n",
1312 printf("--- Exception: %lx %s at ", regs.trap,
1313 getvecname(TRAP(®s)));
1316 xmon_print_symbol(pc, " ", "\n");
1323 } while (count++ < xmon_depth_to_print);
1326 static void backtrace(struct pt_regs *excp)
1331 xmon_show_stack(sp, 0, 0);
1333 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1337 static void print_bug_trap(struct pt_regs *regs)
1339 struct bug_entry *bug;
1342 if (regs->msr & MSR_PR)
1343 return; /* not in kernel */
1344 addr = regs->nip; /* address of trap instruction */
1345 if (addr < PAGE_OFFSET)
1347 bug = find_bug(regs->nip);
1350 if (bug->line & BUG_WARNING_TRAP)
1353 printf("kernel BUG in %s at %s:%d!\n",
1354 bug->function, bug->file, (unsigned int)bug->line);
1357 void excprint(struct pt_regs *fp)
1362 printf("cpu 0x%x: ", smp_processor_id());
1363 #endif /* CONFIG_SMP */
1366 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1368 xmon_print_symbol(fp->nip, ": ", "\n");
1370 printf(" lr: ", fp->link);
1371 xmon_print_symbol(fp->link, ": ", "\n");
1373 printf(" sp: %lx\n", fp->gpr[1]);
1374 printf(" msr: %lx\n", fp->msr);
1376 if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1377 printf(" dar: %lx\n", fp->dar);
1379 printf(" dsisr: %lx\n", fp->dsisr);
1382 printf(" current = 0x%lx\n", current);
1383 printf(" paca = 0x%lx\n", get_paca());
1385 printf(" pid = %ld, comm = %s\n",
1386 current->pid, current->comm);
1393 void prregs(struct pt_regs *fp)
1397 struct pt_regs regs;
1399 if (scanhex(&base)) {
1400 if (setjmp(bus_error_jmp) == 0) {
1401 catch_memory_errors = 1;
1403 regs = *(struct pt_regs *)base;
1407 catch_memory_errors = 0;
1408 printf("*** Error reading registers from %.16lx\n",
1412 catch_memory_errors = 0;
1416 if (FULL_REGS(fp)) {
1417 for (n = 0; n < 16; ++n)
1418 printf("R%.2ld = %.16lx R%.2ld = %.16lx\n",
1419 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1421 for (n = 0; n < 7; ++n)
1422 printf("R%.2ld = %.16lx R%.2ld = %.16lx\n",
1423 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1426 xmon_print_symbol(fp->nip, " ", "\n");
1428 xmon_print_symbol(fp->link, " ", "\n");
1429 printf("msr = %.16lx cr = %.8lx\n", fp->msr, fp->ccr);
1430 printf("ctr = %.16lx xer = %.16lx trap = %8lx\n",
1431 fp->ctr, fp->xer, fp->trap);
1434 void cacheflush(void)
1437 unsigned long nflush;
1442 scanhex((void *)&adrs);
1447 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1448 if (setjmp(bus_error_jmp) == 0) {
1449 catch_memory_errors = 1;
1453 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1454 cflush((void *) adrs);
1456 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1457 cinval((void *) adrs);
1460 /* wait a little while to see if we get a machine check */
1463 catch_memory_errors = 0;
1469 unsigned int instrs[2];
1470 unsigned long (*code)(void);
1471 unsigned long opd[3];
1472 unsigned long ret = -1UL;
1474 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1475 instrs[1] = 0x4e800020;
1476 opd[0] = (unsigned long)instrs;
1480 store_inst(instrs+1);
1481 code = (unsigned long (*)(void)) opd;
1483 if (setjmp(bus_error_jmp) == 0) {
1484 catch_memory_errors = 1;
1490 /* wait a little while to see if we get a machine check */
1499 write_spr(int n, unsigned long val)
1501 unsigned int instrs[2];
1502 unsigned long (*code)(unsigned long);
1503 unsigned long opd[3];
1505 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1506 instrs[1] = 0x4e800020;
1507 opd[0] = (unsigned long)instrs;
1511 store_inst(instrs+1);
1512 code = (unsigned long (*)(unsigned long)) opd;
1514 if (setjmp(bus_error_jmp) == 0) {
1515 catch_memory_errors = 1;
1521 /* wait a little while to see if we get a machine check */
1527 static unsigned long regno;
1528 extern char exc_prolog;
1529 extern char dec_exc;
1536 #ifdef CONFIG_PPC_ISERIES
1537 struct paca_struct *ptrPaca = NULL;
1538 struct lppaca *ptrLpPaca = NULL;
1539 struct ItLpRegSave *ptrLpRegSave = NULL;
1544 unsigned long sp, toc;
1545 asm("mr %0,1" : "=r" (sp) :);
1546 asm("mr %0,2" : "=r" (toc) :);
1548 printf("msr = %.16lx sprg0= %.16lx\n", get_msr(), get_sprg0());
1549 printf("pvr = %.16lx sprg1= %.16lx\n", get_pvr(), get_sprg1());
1550 printf("dec = %.16lx sprg2= %.16lx\n", get_dec(), get_sprg2());
1551 printf("sp = %.16lx sprg3= %.16lx\n", sp, get_sprg3());
1552 printf("toc = %.16lx dar = %.16lx\n", toc, get_dar());
1553 printf("srr0 = %.16lx srr1 = %.16lx\n", get_srr0(), get_srr1());
1554 #ifdef CONFIG_PPC_ISERIES
1555 // Dump out relevant Paca data areas.
1557 ptrPaca = get_paca();
1559 printf(" Local Processor Control Area (LpPaca): \n");
1560 ptrLpPaca = ptrPaca->lppaca_ptr;
1561 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1562 ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
1563 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1564 ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
1565 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
1567 printf(" Local Processor Register Save Area (LpRegSave): \n");
1568 ptrLpRegSave = ptrPaca->reg_save_ptr;
1569 printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n",
1570 ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
1571 printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n",
1572 ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
1573 printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n",
1574 ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
1583 val = read_spr(regno);
1585 write_spr(regno, val);
1588 printf("spr %lx = %lx\n", regno, read_spr(regno));
1600 * Stuff for reading and writing memory safely
1603 mread(unsigned long adrs, void *buf, int size)
1609 if (setjmp(bus_error_jmp) == 0) {
1610 catch_memory_errors = 1;
1616 *(short *)q = *(short *)p;
1619 *(int *)q = *(int *)p;
1622 *(long *)q = *(long *)p;
1625 for( ; n < size; ++n) {
1631 /* wait a little while to see if we get a machine check */
1635 catch_memory_errors = 0;
1640 mwrite(unsigned long adrs, void *buf, int size)
1646 if (setjmp(bus_error_jmp) == 0) {
1647 catch_memory_errors = 1;
1653 *(short *)p = *(short *)q;
1656 *(int *)p = *(int *)q;
1659 *(long *)p = *(long *)q;
1662 for ( ; n < size; ++n) {
1668 /* wait a little while to see if we get a machine check */
1672 printf("*** Error writing address %x\n", adrs + n);
1674 catch_memory_errors = 0;
1678 static int fault_type;
1679 static char *fault_chars[] = { "--", "**", "##" };
1682 handle_fault(struct pt_regs *regs)
1684 switch (TRAP(regs)) {
1696 longjmp(bus_error_jmp, 1);
1701 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1704 byterev(unsigned char *val, int size)
1710 SWAP(val[0], val[1], t);
1713 SWAP(val[0], val[3], t);
1714 SWAP(val[1], val[2], t);
1716 case 8: /* is there really any use for this? */
1717 SWAP(val[0], val[7], t);
1718 SWAP(val[1], val[6], t);
1719 SWAP(val[2], val[5], t);
1720 SWAP(val[3], val[4], t);
1728 static char *memex_help_string =
1729 "Memory examine command usage:\n"
1730 "m [addr] [flags] examine/change memory\n"
1731 " addr is optional. will start where left off.\n"
1732 " flags may include chars from this set:\n"
1733 " b modify by bytes (default)\n"
1734 " w modify by words (2 byte)\n"
1735 " l modify by longs (4 byte)\n"
1736 " d modify by doubleword (8 byte)\n"
1737 " r toggle reverse byte order mode\n"
1738 " n do not read memory (for i/o spaces)\n"
1739 " . ok to read (default)\n"
1740 "NOTE: flags are saved as defaults\n"
1743 static char *memex_subcmd_help_string =
1744 "Memory examine subcommands:\n"
1745 " hexval write this val to current location\n"
1746 " 'string' write chars from string to this location\n"
1747 " ' increment address\n"
1748 " ^ decrement address\n"
1749 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1750 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1751 " ` clear no-read flag\n"
1752 " ; stay at this addr\n"
1753 " v change to byte mode\n"
1754 " w change to word (2 byte) mode\n"
1755 " l change to long (4 byte) mode\n"
1756 " u change to doubleword (8 byte) mode\n"
1757 " m addr change current addr\n"
1758 " n toggle no-read flag\n"
1759 " r toggle byte reverse flag\n"
1760 " < count back up count bytes\n"
1761 " > count skip forward count bytes\n"
1762 " x exit this mode\n"
1768 int cmd, inc, i, nslash;
1770 unsigned char val[16];
1772 scanhex((void *)&adrs);
1775 printf(memex_help_string);
1781 while ((cmd = skipbl()) != '\n') {
1783 case 'b': size = 1; break;
1784 case 'w': size = 2; break;
1785 case 'l': size = 4; break;
1786 case 'd': size = 8; break;
1787 case 'r': brev = !brev; break;
1788 case 'n': mnoread = 1; break;
1789 case '.': mnoread = 0; break;
1798 n = mread(adrs, val, size);
1799 printf("%.16x%c", adrs, brev? 'r': ' ');
1804 for (i = 0; i < n; ++i)
1805 printf("%.2x", val[i]);
1806 for (; i < size; ++i)
1807 printf("%s", fault_chars[fault_type]);
1814 for (i = 0; i < size; ++i)
1815 val[i] = n >> (i * 8);
1818 mwrite(adrs, val, size);
1831 else if( n == '\'' )
1833 for (i = 0; i < size; ++i)
1834 val[i] = n >> (i * 8);
1837 mwrite(adrs, val, size);
1874 adrs -= 1 << nslash;
1878 adrs += 1 << nslash;
1882 adrs += 1 << -nslash;
1886 adrs -= 1 << -nslash;
1889 scanhex((void *)&adrs);
1908 printf(memex_subcmd_help_string);
1923 case 'n': c = '\n'; break;
1924 case 'r': c = '\r'; break;
1925 case 'b': c = '\b'; break;
1926 case 't': c = '\t'; break;
1931 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
1932 || ('a' <= (c) && (c) <= 'f') \
1933 || ('A' <= (c) && (c) <= 'F'))
1940 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
1942 scanhex((void *)&adrs);
1949 else if (nidump > MAX_DUMP)
1951 adrs += ppc_inst_dump(adrs, nidump, 1);
1957 else if (ndump > MAX_DUMP)
1959 prdump(adrs, ndump);
1966 prdump(unsigned long adrs, long ndump)
1968 long n, m, c, r, nr;
1969 unsigned char temp[16];
1971 for (n = ndump; n > 0;) {
1972 printf("%.16lx", adrs);
1975 nr = mread(adrs, temp, r);
1977 for (m = 0; m < r; ++m) {
1978 if ((m & 7) == 0 && m > 0)
1981 printf("%.2x", temp[m]);
1983 printf("%s", fault_chars[fault_type]);
1990 for (m = 0; m < r; ++m) {
1993 putchar(' ' <= c && c <= '~'? c: '.');
2007 ppc_inst_dump(unsigned long adr, long count, int praddr)
2010 unsigned long first_adr;
2011 unsigned long inst, last_inst = 0;
2012 unsigned char val[4];
2015 for (first_adr = adr; count > 0; --count, adr += 4) {
2016 nr = mread(adr, val, 4);
2019 const char *x = fault_chars[fault_type];
2020 printf("%.16lx %s%s%s%s\n", adr, x, x, x, x);
2024 inst = GETWORD(val);
2025 if (adr > first_adr && inst == last_inst) {
2035 printf("%.16lx %.8x", adr, inst);
2037 print_insn_powerpc(inst, adr, 0); /* always returns 4 */
2040 return adr - first_adr;
2044 print_address(unsigned long addr)
2046 xmon_print_symbol(addr, "\t# ", "");
2051 * Memory operations - move, set, print differences
2053 static unsigned long mdest; /* destination address */
2054 static unsigned long msrc; /* source address */
2055 static unsigned long mval; /* byte value to set memory to */
2056 static unsigned long mcount; /* # bytes to affect */
2057 static unsigned long mdiffs; /* max # differences to print */
2062 scanhex((void *)&mdest);
2063 if( termch != '\n' )
2065 scanhex((void *)(cmd == 's'? &mval: &msrc));
2066 if( termch != '\n' )
2068 scanhex((void *)&mcount);
2071 memmove((void *)mdest, (void *)msrc, mcount);
2074 memset((void *)mdest, mval, mcount);
2077 if( termch != '\n' )
2079 scanhex((void *)&mdiffs);
2080 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2086 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2091 for( n = nb; n > 0; --n )
2092 if( *p1++ != *p2++ )
2093 if( ++prt <= maxpr )
2094 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2095 p1[-1], p2 - 1, p2[-1]);
2097 printf("Total of %d differences\n", prt);
2100 static unsigned mend;
2101 static unsigned mask;
2107 unsigned char val[4];
2110 scanhex((void *)&mdest);
2111 if (termch != '\n') {
2113 scanhex((void *)&mend);
2114 if (termch != '\n') {
2116 scanhex((void *)&mval);
2118 if (termch != '\n') termch = 0;
2119 scanhex((void *)&mask);
2123 for (a = mdest; a < mend; a += 4) {
2124 if (mread(a, val, 4) == 4
2125 && ((GETWORD(val) ^ mval) & mask) == 0) {
2126 printf("%.16x: %.16x\n", a, GETWORD(val));
2133 static unsigned long mskip = 0x1000;
2134 static unsigned long mlim = 0xffffffff;
2144 if (termch != '\n') termch = 0;
2146 if (termch != '\n') termch = 0;
2149 for (a = mdest; a < mlim; a += mskip) {
2150 ok = mread(a, &v, 1);
2152 printf("%.8x .. ", a);
2154 } else if (!ok && ook)
2155 printf("%.8x\n", a - mskip);
2161 printf("%.8x\n", a - mskip);
2164 /* Input scanning routines */
2175 while( c == ' ' || c == '\t' )
2181 static char *regnames[N_PTREGS] = {
2182 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2183 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2184 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2185 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2186 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", "softe",
2187 "trap", "dar", "dsisr", "res"
2191 scanhex(unsigned long *vp)
2198 /* parse register name */
2202 for (i = 0; i < sizeof(regname) - 1; ++i) {
2211 for (i = 0; i < N_PTREGS; ++i) {
2212 if (strcmp(regnames[i], regname) == 0) {
2213 if (xmon_regs == NULL) {
2214 printf("regs not available\n");
2217 *vp = ((unsigned long *)xmon_regs)[i];
2221 printf("invalid register name '%%%s'\n", regname);
2225 /* skip leading "0x" if any */
2239 } else if (c == '$') {
2241 for (i=0; i<63; i++) {
2251 if (setjmp(bus_error_jmp) == 0) {
2252 catch_memory_errors = 1;
2254 *vp = kallsyms_lookup_name(tmpstr);
2257 catch_memory_errors = 0;
2259 printf("unknown symbol '%s'\n", tmpstr);
2295 if( '0' <= c && c <= '9' )
2297 if( 'A' <= c && c <= 'F' )
2298 return c - ('A' - 10);
2299 if( 'a' <= c && c <= 'f' )
2300 return c - ('a' - 10);
2305 getstring(char *s, int size)
2316 } while( c != ' ' && c != '\t' && c != '\n' );
2321 static char line[256];
2322 static char *lineptr;
2333 if (lineptr == NULL || *lineptr == 0) {
2334 if (fgets(line, sizeof(line), stdin) == NULL) {
2344 take_input(char *str)
2353 int type = inchar();
2355 static char tmp[64];
2360 xmon_print_symbol(addr, ": ", "\n");
2365 if (setjmp(bus_error_jmp) == 0) {
2366 catch_memory_errors = 1;
2368 addr = kallsyms_lookup_name(tmp);
2370 printf("%s: %lx\n", tmp, addr);
2372 printf("Symbol '%s' not found.\n", tmp);
2375 catch_memory_errors = 0;
2382 /* Print an address in numeric and symbolic form (if possible) */
2383 static void xmon_print_symbol(unsigned long address, const char *mid,
2387 const char *name = NULL;
2388 unsigned long offset, size;
2390 printf("%.16lx", address);
2391 if (setjmp(bus_error_jmp) == 0) {
2392 catch_memory_errors = 1;
2394 name = kallsyms_lookup(address, &size, &offset, &modname,
2397 /* wait a little while to see if we get a machine check */
2401 catch_memory_errors = 0;
2404 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2406 printf(" [%s]", modname);
2408 printf("%s", after);
2411 static void debug_trace(void)
2413 unsigned long val, cmd, on;
2417 /* show current state */
2419 printf("ppc64_debug_switch = 0x%lx\n", ppc64_debug_switch);
2420 for (i = 0; i < PPCDBG_NUM_FLAGS ;i++) {
2421 on = PPCDBG_BITVAL(i) & ppc64_debug_switch;
2422 printf("%02x %s %12s ", i, on ? "on " : "off", trace_names[i] ? trace_names[i] : "");
2423 if (((i+1) % 3) == 0)
2429 while (cmd != '\n') {
2430 on = 1; /* default if no sign given */
2431 while (cmd == '+' || cmd == '-') {
2434 if (cmd == ' ' || cmd == '\n') { /* Turn on or off based on + or - */
2435 ppc64_debug_switch = on ? PPCDBG_ALL:PPCDBG_NONE;
2436 printf("Setting all values to %s...\n", on ? "on" : "off");
2437 if (cmd == '\n') return;
2438 else cmd = skipbl();
2443 termch = cmd; /* not +/- ... let scanhex see it */
2444 scanhex((void *)&val);
2446 printf("Value %x out of range:\n", val);
2450 ppc64_debug_switch |= PPCDBG_BITVAL(val);
2451 printf("enable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
2453 ppc64_debug_switch &= ~PPCDBG_BITVAL(val);
2454 printf("disable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
2460 static void dump_slb(void)
2465 printf("SLB contents of cpu %x\n", smp_processor_id());
2467 for (i = 0; i < SLB_NUM_ENTRIES; i++) {
2468 asm volatile("slbmfee %0,%1" : "=r" (tmp) : "r" (i));
2469 printf("%02d %016lx ", i, tmp);
2471 asm volatile("slbmfev %0,%1" : "=r" (tmp) : "r" (i));
2472 printf("%016lx\n", tmp);
2476 static void dump_stab(void)
2479 unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2481 printf("Segment table contents of cpu %x\n", smp_processor_id());
2483 for (i = 0; i < PAGE_SIZE/16; i++) {
2490 printf("%03d %016lx ", i, a);
2491 printf("%016lx\n", b);
2496 void xmon_init(void)
2499 __debugger_ipi = xmon_ipi;
2500 __debugger_bpt = xmon_bpt;
2501 __debugger_sstep = xmon_sstep;
2502 __debugger_iabr_match = xmon_iabr_match;
2503 __debugger_dabr_match = xmon_dabr_match;
2504 __debugger_fault_handler = xmon_fault_handler;
2507 void dump_segments(void)
2509 if (cpu_has_feature(CPU_FTR_SLB))