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))
593 int xmon_iabr_match(struct pt_regs *regs)
595 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
603 int xmon_ipi(struct pt_regs *regs)
606 if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
612 int xmon_fault_handler(struct pt_regs *regs)
615 unsigned long offset;
617 if (in_xmon && catch_memory_errors)
618 handle_fault(regs); /* doesn't return */
620 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
621 bp = in_breakpoint_table(regs->nip, &offset);
623 regs->nip = bp->address + offset;
624 atomic_dec(&bp->ref_count);
631 /* On systems with a hypervisor, we can't set the DABR
632 (data address breakpoint register) directly. */
633 static void set_controlled_dabr(unsigned long val)
635 #ifdef CONFIG_PPC_PSERIES
636 if (systemcfg->platform == PLATFORM_PSERIES_LPAR) {
637 int rc = plpar_hcall_norets(H_SET_DABR, val);
639 xmon_printf("Warning: setting DABR failed (%d)\n", rc);
645 static struct bpt *at_breakpoint(unsigned long pc)
651 for (i = 0; i < NBPTS; ++i, ++bp)
652 if (bp->enabled && pc == bp->address)
657 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
661 off = nip - (unsigned long) bpts;
662 if (off >= sizeof(bpts))
664 off %= sizeof(struct bpt);
665 if (off != offsetof(struct bpt, instr[0])
666 && off != offsetof(struct bpt, instr[1]))
668 *offp = off - offsetof(struct bpt, instr[0]);
669 return (struct bpt *) (nip - off);
672 static struct bpt *new_breakpoint(unsigned long a)
677 bp = at_breakpoint(a);
681 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
682 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
684 bp->instr[1] = bpinstr;
685 store_inst(&bp->instr[1]);
690 printf("Sorry, no free breakpoints. Please clear one first.\n");
694 static void insert_bpts(void)
700 for (i = 0; i < NBPTS; ++i, ++bp) {
701 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
703 if (mread(bp->address, &bp->instr[0], 4) != 4) {
704 printf("Couldn't read instruction at %lx, "
705 "disabling breakpoint there\n", bp->address);
709 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
710 printf("Breakpoint at %lx is on an mtmsrd or rfid "
711 "instruction, disabling it\n", bp->address);
715 store_inst(&bp->instr[0]);
716 if (bp->enabled & BP_IABR)
718 if (mwrite(bp->address, &bpinstr, 4) != 4) {
719 printf("Couldn't write instruction at %lx, "
720 "disabling breakpoint there\n", bp->address);
721 bp->enabled &= ~BP_TRAP;
724 store_inst((void *)bp->address);
728 static void insert_cpu_bpts(void)
731 set_controlled_dabr(dabr.address | (dabr.enabled & 7));
732 if (iabr && cpu_has_feature(CPU_FTR_IABR))
733 set_iabr(iabr->address
734 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
737 static void remove_bpts(void)
744 for (i = 0; i < NBPTS; ++i, ++bp) {
745 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
747 if (mread(bp->address, &instr, 4) == 4
749 && mwrite(bp->address, &bp->instr, 4) != 4)
750 printf("Couldn't remove breakpoint at %lx\n",
753 store_inst((void *)bp->address);
757 static void remove_cpu_bpts(void)
759 set_controlled_dabr(0);
760 if (cpu_has_feature(CPU_FTR_IABR))
764 /* Command interpreting routine */
765 static char *last_cmd;
768 cmds(struct pt_regs *excp)
776 printf("%x:", smp_processor_id());
777 #endif /* CONFIG_SMP */
784 if (last_cmd == NULL)
786 take_input(last_cmd);
820 prregs(excp); /* print regs */
868 printf("Unrecognized command: ");
870 if (' ' < cmd && cmd <= '~')
873 printf("\\x%x", cmd);
875 } while (cmd != '\n');
876 printf(" (type ? for help)\n");
883 * Step a single instruction.
884 * Some instructions we emulate, others we execute with MSR_SE set.
886 static int do_step(struct pt_regs *regs)
891 /* check we are in 64-bit kernel mode, translation enabled */
892 if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
893 if (mread(regs->nip, &instr, 4) == 4) {
894 stepped = emulate_step(regs, instr);
896 printf("Couldn't single-step %s instruction\n",
897 (IS_RFID(instr)? "rfid": "mtmsrd"));
901 regs->trap = 0xd00 | (regs->trap & 1);
902 printf("stepped to ");
903 xmon_print_symbol(regs->nip, " ", "\n");
904 ppc_inst_dump(regs->nip, 1, 0);
913 static void bootcmds(void)
919 ppc_md.restart(NULL);
926 static int cpu_cmd(void)
933 if (!scanhex(&cpu)) {
934 /* print cpus waiting or in xmon */
935 printf("cpus stopped:");
937 for (cpu = 0; cpu < NR_CPUS; ++cpu) {
938 if (cpu_isset(cpu, cpus_in_xmon)) {
944 printf("-%x", cpu - 1);
949 printf("-%x", NR_CPUS - 1);
953 /* try to switch to cpu specified */
954 if (!cpu_isset(cpu, cpus_in_xmon)) {
955 printf("cpu 0x%x isn't in xmon\n", cpu);
962 while (!xmon_taken) {
963 if (--timeout == 0) {
964 if (test_and_set_bit(0, &xmon_taken))
966 /* take control back */
968 xmon_owner = smp_processor_id();
969 printf("cpu %u didn't take control\n", cpu);
977 #endif /* CONFIG_SMP */
980 static unsigned short fcstab[256] = {
981 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
982 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
983 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
984 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
985 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
986 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
987 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
988 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
989 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
990 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
991 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
992 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
993 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
994 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
995 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
996 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
997 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
998 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
999 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1000 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1001 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1002 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1003 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1004 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1005 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1006 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1007 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1008 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1009 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1010 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1011 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1012 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1015 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1024 if (!scanhex(&adrs))
1026 if (!scanhex(&ncsum))
1029 for (i = 0; i < ncsum; ++i) {
1030 if (mread(adrs+i, &v, 1) == 0) {
1031 printf("csum stopped at %x\n", adrs+i);
1036 printf("%x\n", fcs);
1040 * Check if this is a suitable place to put a breakpoint.
1042 static long check_bp_loc(unsigned long addr)
1047 if (addr < KERNELBASE) {
1048 printf("Breakpoints may only be placed at kernel addresses\n");
1051 if (!mread(addr, &instr, sizeof(instr))) {
1052 printf("Can't read instruction at address %lx\n", addr);
1055 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1056 printf("Breakpoints may not be placed on mtmsrd or rfid "
1063 static char *breakpoint_help_string =
1064 "Breakpoint command usage:\n"
1065 "b show breakpoints\n"
1066 "b <addr> [cnt] set breakpoint at given instr addr\n"
1067 "bc clear all breakpoints\n"
1068 "bc <n/addr> clear breakpoint number n or at addr\n"
1069 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1070 "bd <addr> [cnt] set hardware data breakpoint\n"
1080 const char badaddr[] = "Only kernel addresses are permitted "
1081 "for breakpoints\n";
1085 case 'd': /* bd - hardware data breakpoint */
1090 else if (cmd == 'w')
1096 if (scanhex(&dabr.address)) {
1097 if (dabr.address < KERNELBASE) {
1102 dabr.enabled = mode | BP_DABR;
1106 case 'i': /* bi - hardware instr breakpoint */
1107 if (!cpu_has_feature(CPU_FTR_IABR)) {
1108 printf("Hardware instruction breakpoint "
1109 "not supported on this cpu\n");
1113 iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1118 if (!check_bp_loc(a))
1120 bp = new_breakpoint(a);
1122 bp->enabled |= BP_IABR | BP_IABR_TE;
1129 /* clear all breakpoints */
1130 for (i = 0; i < NBPTS; ++i)
1131 bpts[i].enabled = 0;
1134 printf("All breakpoints cleared\n");
1138 if (a <= NBPTS && a >= 1) {
1139 /* assume a breakpoint number */
1140 bp = &bpts[a-1]; /* bp nums are 1 based */
1142 /* assume a breakpoint address */
1143 bp = at_breakpoint(a);
1145 printf("No breakpoint at %x\n", a);
1150 printf("Cleared breakpoint %x (", BP_NUM(bp));
1151 xmon_print_symbol(bp->address, " ", ")\n");
1159 printf(breakpoint_help_string);
1164 /* print all breakpoints */
1165 printf(" type address\n");
1167 printf(" data %.16lx [", dabr.address);
1168 if (dabr.enabled & 1)
1170 if (dabr.enabled & 2)
1174 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1177 printf("%2x %s ", BP_NUM(bp),
1178 (bp->enabled & BP_IABR)? "inst": "trap");
1179 xmon_print_symbol(bp->address, " ", "\n");
1184 if (!check_bp_loc(a))
1186 bp = new_breakpoint(a);
1188 bp->enabled |= BP_TRAP;
1193 /* Very cheap human name for vector lookup. */
1195 const char *getvecname(unsigned long vec)
1200 case 0x100: ret = "(System Reset)"; break;
1201 case 0x200: ret = "(Machine Check)"; break;
1202 case 0x300: ret = "(Data Access)"; break;
1203 case 0x380: ret = "(Data SLB Access)"; break;
1204 case 0x400: ret = "(Instruction Access)"; break;
1205 case 0x480: ret = "(Instruction SLB Access)"; break;
1206 case 0x500: ret = "(Hardware Interrupt)"; break;
1207 case 0x600: ret = "(Alignment)"; break;
1208 case 0x700: ret = "(Program Check)"; break;
1209 case 0x800: ret = "(FPU Unavailable)"; break;
1210 case 0x900: ret = "(Decrementer)"; break;
1211 case 0xc00: ret = "(System Call)"; break;
1212 case 0xd00: ret = "(Single Step)"; break;
1213 case 0xf00: ret = "(Performance Monitor)"; break;
1214 case 0xf20: ret = "(Altivec Unavailable)"; break;
1215 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1221 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1222 unsigned long *endp)
1224 unsigned long size, offset;
1228 *startp = *endp = 0;
1231 if (setjmp(bus_error_jmp) == 0) {
1232 catch_memory_errors = 1;
1234 name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr);
1236 *startp = pc - offset;
1237 *endp = pc - offset + size;
1241 catch_memory_errors = 0;
1244 static int xmon_depth_to_print = 64;
1246 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1250 unsigned long newsp;
1251 unsigned long marker;
1253 struct pt_regs regs;
1256 if (sp < PAGE_OFFSET) {
1258 printf("SP (%lx) is in userspace\n", sp);
1262 if (!mread(sp + 16, &ip, sizeof(unsigned long))
1263 || !mread(sp, &newsp, sizeof(unsigned long))) {
1264 printf("Couldn't read stack frame at %lx\n", sp);
1269 * For the first stack frame, try to work out if
1270 * LR and/or the saved LR value in the bottommost
1271 * stack frame are valid.
1273 if ((pc | lr) != 0) {
1274 unsigned long fnstart, fnend;
1275 unsigned long nextip;
1278 get_function_bounds(pc, &fnstart, &fnend);
1281 mread(newsp + 16, &nextip,
1282 sizeof(unsigned long));
1284 if (lr < PAGE_OFFSET
1285 || (fnstart <= lr && lr < fnend))
1287 } else if (lr == nextip) {
1289 } else if (lr >= PAGE_OFFSET
1290 && !(fnstart <= lr && lr < fnend)) {
1291 printf("[link register ] ");
1292 xmon_print_symbol(lr, " ", "\n");
1295 printf("[%.16lx] ", sp);
1296 xmon_print_symbol(ip, " ", " (unreliable)\n");
1301 printf("[%.16lx] ", sp);
1302 xmon_print_symbol(ip, " ", "\n");
1305 /* Look for "regshere" marker to see if this is
1306 an exception frame. */
1307 if (mread(sp + 0x60, &marker, sizeof(unsigned long))
1308 && marker == 0x7265677368657265ul) {
1309 if (mread(sp + 0x70, ®s, sizeof(regs))
1311 printf("Couldn't read registers at %lx\n",
1315 printf("--- Exception: %lx %s at ", regs.trap,
1316 getvecname(TRAP(®s)));
1319 xmon_print_symbol(pc, " ", "\n");
1326 } while (count++ < xmon_depth_to_print);
1329 static void backtrace(struct pt_regs *excp)
1334 xmon_show_stack(sp, 0, 0);
1336 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1340 static void print_bug_trap(struct pt_regs *regs)
1342 struct bug_entry *bug;
1345 if (regs->msr & MSR_PR)
1346 return; /* not in kernel */
1347 addr = regs->nip; /* address of trap instruction */
1348 if (addr < PAGE_OFFSET)
1350 bug = find_bug(regs->nip);
1353 if (bug->line & BUG_WARNING_TRAP)
1356 printf("kernel BUG in %s at %s:%d!\n",
1357 bug->function, bug->file, (unsigned int)bug->line);
1360 void excprint(struct pt_regs *fp)
1365 printf("cpu 0x%x: ", smp_processor_id());
1366 #endif /* CONFIG_SMP */
1369 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1371 xmon_print_symbol(fp->nip, ": ", "\n");
1373 printf(" lr: ", fp->link);
1374 xmon_print_symbol(fp->link, ": ", "\n");
1376 printf(" sp: %lx\n", fp->gpr[1]);
1377 printf(" msr: %lx\n", fp->msr);
1379 if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1380 printf(" dar: %lx\n", fp->dar);
1382 printf(" dsisr: %lx\n", fp->dsisr);
1385 printf(" current = 0x%lx\n", current);
1386 printf(" paca = 0x%lx\n", get_paca());
1388 printf(" pid = %ld, comm = %s\n",
1389 current->pid, current->comm);
1396 void prregs(struct pt_regs *fp)
1400 struct pt_regs regs;
1402 if (scanhex(&base)) {
1403 if (setjmp(bus_error_jmp) == 0) {
1404 catch_memory_errors = 1;
1406 regs = *(struct pt_regs *)base;
1410 catch_memory_errors = 0;
1411 printf("*** Error reading registers from %.16lx\n",
1415 catch_memory_errors = 0;
1419 if (FULL_REGS(fp)) {
1420 for (n = 0; n < 16; ++n)
1421 printf("R%.2ld = %.16lx R%.2ld = %.16lx\n",
1422 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1424 for (n = 0; n < 7; ++n)
1425 printf("R%.2ld = %.16lx R%.2ld = %.16lx\n",
1426 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1429 xmon_print_symbol(fp->nip, " ", "\n");
1431 xmon_print_symbol(fp->link, " ", "\n");
1432 printf("msr = %.16lx cr = %.8lx\n", fp->msr, fp->ccr);
1433 printf("ctr = %.16lx xer = %.16lx trap = %8lx\n",
1434 fp->ctr, fp->xer, fp->trap);
1437 void cacheflush(void)
1440 unsigned long nflush;
1445 scanhex((void *)&adrs);
1450 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1451 if (setjmp(bus_error_jmp) == 0) {
1452 catch_memory_errors = 1;
1456 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1457 cflush((void *) adrs);
1459 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1460 cinval((void *) adrs);
1463 /* wait a little while to see if we get a machine check */
1466 catch_memory_errors = 0;
1472 unsigned int instrs[2];
1473 unsigned long (*code)(void);
1474 unsigned long opd[3];
1475 unsigned long ret = -1UL;
1477 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1478 instrs[1] = 0x4e800020;
1479 opd[0] = (unsigned long)instrs;
1483 store_inst(instrs+1);
1484 code = (unsigned long (*)(void)) opd;
1486 if (setjmp(bus_error_jmp) == 0) {
1487 catch_memory_errors = 1;
1493 /* wait a little while to see if we get a machine check */
1502 write_spr(int n, unsigned long val)
1504 unsigned int instrs[2];
1505 unsigned long (*code)(unsigned long);
1506 unsigned long opd[3];
1508 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1509 instrs[1] = 0x4e800020;
1510 opd[0] = (unsigned long)instrs;
1514 store_inst(instrs+1);
1515 code = (unsigned long (*)(unsigned long)) opd;
1517 if (setjmp(bus_error_jmp) == 0) {
1518 catch_memory_errors = 1;
1524 /* wait a little while to see if we get a machine check */
1530 static unsigned long regno;
1531 extern char exc_prolog;
1532 extern char dec_exc;
1539 #ifdef CONFIG_PPC_ISERIES
1540 struct paca_struct *ptrPaca = NULL;
1541 struct lppaca *ptrLpPaca = NULL;
1542 struct ItLpRegSave *ptrLpRegSave = NULL;
1547 unsigned long sp, toc;
1548 asm("mr %0,1" : "=r" (sp) :);
1549 asm("mr %0,2" : "=r" (toc) :);
1551 printf("msr = %.16lx sprg0= %.16lx\n", get_msr(), get_sprg0());
1552 printf("pvr = %.16lx sprg1= %.16lx\n", get_pvr(), get_sprg1());
1553 printf("dec = %.16lx sprg2= %.16lx\n", get_dec(), get_sprg2());
1554 printf("sp = %.16lx sprg3= %.16lx\n", sp, get_sprg3());
1555 printf("toc = %.16lx dar = %.16lx\n", toc, get_dar());
1556 printf("srr0 = %.16lx srr1 = %.16lx\n", get_srr0(), get_srr1());
1557 #ifdef CONFIG_PPC_ISERIES
1558 // Dump out relevant Paca data areas.
1560 ptrPaca = get_paca();
1562 printf(" Local Processor Control Area (LpPaca): \n");
1563 ptrLpPaca = ptrPaca->lppaca_ptr;
1564 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1565 ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
1566 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1567 ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
1568 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
1570 printf(" Local Processor Register Save Area (LpRegSave): \n");
1571 ptrLpRegSave = ptrPaca->reg_save_ptr;
1572 printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n",
1573 ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
1574 printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n",
1575 ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
1576 printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n",
1577 ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
1586 val = read_spr(regno);
1588 write_spr(regno, val);
1591 printf("spr %lx = %lx\n", regno, read_spr(regno));
1603 * Stuff for reading and writing memory safely
1606 mread(unsigned long adrs, void *buf, int size)
1612 if (setjmp(bus_error_jmp) == 0) {
1613 catch_memory_errors = 1;
1619 *(short *)q = *(short *)p;
1622 *(int *)q = *(int *)p;
1625 *(long *)q = *(long *)p;
1628 for( ; n < size; ++n) {
1634 /* wait a little while to see if we get a machine check */
1638 catch_memory_errors = 0;
1643 mwrite(unsigned long adrs, void *buf, int size)
1649 if (setjmp(bus_error_jmp) == 0) {
1650 catch_memory_errors = 1;
1656 *(short *)p = *(short *)q;
1659 *(int *)p = *(int *)q;
1662 *(long *)p = *(long *)q;
1665 for ( ; n < size; ++n) {
1671 /* wait a little while to see if we get a machine check */
1675 printf("*** Error writing address %x\n", adrs + n);
1677 catch_memory_errors = 0;
1681 static int fault_type;
1682 static char *fault_chars[] = { "--", "**", "##" };
1685 handle_fault(struct pt_regs *regs)
1687 switch (TRAP(regs)) {
1699 longjmp(bus_error_jmp, 1);
1704 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1707 byterev(unsigned char *val, int size)
1713 SWAP(val[0], val[1], t);
1716 SWAP(val[0], val[3], t);
1717 SWAP(val[1], val[2], t);
1719 case 8: /* is there really any use for this? */
1720 SWAP(val[0], val[7], t);
1721 SWAP(val[1], val[6], t);
1722 SWAP(val[2], val[5], t);
1723 SWAP(val[3], val[4], t);
1731 static char *memex_help_string =
1732 "Memory examine command usage:\n"
1733 "m [addr] [flags] examine/change memory\n"
1734 " addr is optional. will start where left off.\n"
1735 " flags may include chars from this set:\n"
1736 " b modify by bytes (default)\n"
1737 " w modify by words (2 byte)\n"
1738 " l modify by longs (4 byte)\n"
1739 " d modify by doubleword (8 byte)\n"
1740 " r toggle reverse byte order mode\n"
1741 " n do not read memory (for i/o spaces)\n"
1742 " . ok to read (default)\n"
1743 "NOTE: flags are saved as defaults\n"
1746 static char *memex_subcmd_help_string =
1747 "Memory examine subcommands:\n"
1748 " hexval write this val to current location\n"
1749 " 'string' write chars from string to this location\n"
1750 " ' increment address\n"
1751 " ^ decrement address\n"
1752 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1753 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1754 " ` clear no-read flag\n"
1755 " ; stay at this addr\n"
1756 " v change to byte mode\n"
1757 " w change to word (2 byte) mode\n"
1758 " l change to long (4 byte) mode\n"
1759 " u change to doubleword (8 byte) mode\n"
1760 " m addr change current addr\n"
1761 " n toggle no-read flag\n"
1762 " r toggle byte reverse flag\n"
1763 " < count back up count bytes\n"
1764 " > count skip forward count bytes\n"
1765 " x exit this mode\n"
1771 int cmd, inc, i, nslash;
1773 unsigned char val[16];
1775 scanhex((void *)&adrs);
1778 printf(memex_help_string);
1784 while ((cmd = skipbl()) != '\n') {
1786 case 'b': size = 1; break;
1787 case 'w': size = 2; break;
1788 case 'l': size = 4; break;
1789 case 'd': size = 8; break;
1790 case 'r': brev = !brev; break;
1791 case 'n': mnoread = 1; break;
1792 case '.': mnoread = 0; break;
1801 n = mread(adrs, val, size);
1802 printf("%.16x%c", adrs, brev? 'r': ' ');
1807 for (i = 0; i < n; ++i)
1808 printf("%.2x", val[i]);
1809 for (; i < size; ++i)
1810 printf("%s", fault_chars[fault_type]);
1817 for (i = 0; i < size; ++i)
1818 val[i] = n >> (i * 8);
1821 mwrite(adrs, val, size);
1834 else if( n == '\'' )
1836 for (i = 0; i < size; ++i)
1837 val[i] = n >> (i * 8);
1840 mwrite(adrs, val, size);
1877 adrs -= 1 << nslash;
1881 adrs += 1 << nslash;
1885 adrs += 1 << -nslash;
1889 adrs -= 1 << -nslash;
1892 scanhex((void *)&adrs);
1911 printf(memex_subcmd_help_string);
1926 case 'n': c = '\n'; break;
1927 case 'r': c = '\r'; break;
1928 case 'b': c = '\b'; break;
1929 case 't': c = '\t'; break;
1934 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
1935 || ('a' <= (c) && (c) <= 'f') \
1936 || ('A' <= (c) && (c) <= 'F'))
1943 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
1945 scanhex((void *)&adrs);
1952 else if (nidump > MAX_DUMP)
1954 adrs += ppc_inst_dump(adrs, nidump, 1);
1960 else if (ndump > MAX_DUMP)
1962 prdump(adrs, ndump);
1969 prdump(unsigned long adrs, long ndump)
1971 long n, m, c, r, nr;
1972 unsigned char temp[16];
1974 for (n = ndump; n > 0;) {
1975 printf("%.16lx", adrs);
1978 nr = mread(adrs, temp, r);
1980 for (m = 0; m < r; ++m) {
1981 if ((m & 7) == 0 && m > 0)
1984 printf("%.2x", temp[m]);
1986 printf("%s", fault_chars[fault_type]);
1993 for (m = 0; m < r; ++m) {
1996 putchar(' ' <= c && c <= '~'? c: '.');
2010 ppc_inst_dump(unsigned long adr, long count, int praddr)
2013 unsigned long first_adr;
2014 unsigned long inst, last_inst = 0;
2015 unsigned char val[4];
2018 for (first_adr = adr; count > 0; --count, adr += 4) {
2019 nr = mread(adr, val, 4);
2022 const char *x = fault_chars[fault_type];
2023 printf("%.16lx %s%s%s%s\n", adr, x, x, x, x);
2027 inst = GETWORD(val);
2028 if (adr > first_adr && inst == last_inst) {
2038 printf("%.16lx %.8x", adr, inst);
2040 print_insn_powerpc(inst, adr, 0); /* always returns 4 */
2043 return adr - first_adr;
2047 print_address(unsigned long addr)
2049 xmon_print_symbol(addr, "\t# ", "");
2054 * Memory operations - move, set, print differences
2056 static unsigned long mdest; /* destination address */
2057 static unsigned long msrc; /* source address */
2058 static unsigned long mval; /* byte value to set memory to */
2059 static unsigned long mcount; /* # bytes to affect */
2060 static unsigned long mdiffs; /* max # differences to print */
2065 scanhex((void *)&mdest);
2066 if( termch != '\n' )
2068 scanhex((void *)(cmd == 's'? &mval: &msrc));
2069 if( termch != '\n' )
2071 scanhex((void *)&mcount);
2074 memmove((void *)mdest, (void *)msrc, mcount);
2077 memset((void *)mdest, mval, mcount);
2080 if( termch != '\n' )
2082 scanhex((void *)&mdiffs);
2083 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2089 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2094 for( n = nb; n > 0; --n )
2095 if( *p1++ != *p2++ )
2096 if( ++prt <= maxpr )
2097 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2098 p1[-1], p2 - 1, p2[-1]);
2100 printf("Total of %d differences\n", prt);
2103 static unsigned mend;
2104 static unsigned mask;
2110 unsigned char val[4];
2113 scanhex((void *)&mdest);
2114 if (termch != '\n') {
2116 scanhex((void *)&mend);
2117 if (termch != '\n') {
2119 scanhex((void *)&mval);
2121 if (termch != '\n') termch = 0;
2122 scanhex((void *)&mask);
2126 for (a = mdest; a < mend; a += 4) {
2127 if (mread(a, val, 4) == 4
2128 && ((GETWORD(val) ^ mval) & mask) == 0) {
2129 printf("%.16x: %.16x\n", a, GETWORD(val));
2136 static unsigned long mskip = 0x1000;
2137 static unsigned long mlim = 0xffffffff;
2147 if (termch != '\n') termch = 0;
2149 if (termch != '\n') termch = 0;
2152 for (a = mdest; a < mlim; a += mskip) {
2153 ok = mread(a, &v, 1);
2155 printf("%.8x .. ", a);
2157 } else if (!ok && ook)
2158 printf("%.8x\n", a - mskip);
2164 printf("%.8x\n", a - mskip);
2167 /* Input scanning routines */
2178 while( c == ' ' || c == '\t' )
2184 static char *regnames[N_PTREGS] = {
2185 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2186 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2187 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2188 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2189 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", "softe",
2190 "trap", "dar", "dsisr", "res"
2194 scanhex(unsigned long *vp)
2201 /* parse register name */
2205 for (i = 0; i < sizeof(regname) - 1; ++i) {
2214 for (i = 0; i < N_PTREGS; ++i) {
2215 if (strcmp(regnames[i], regname) == 0) {
2216 if (xmon_regs == NULL) {
2217 printf("regs not available\n");
2220 *vp = ((unsigned long *)xmon_regs)[i];
2224 printf("invalid register name '%%%s'\n", regname);
2228 /* skip leading "0x" if any */
2242 } else if (c == '$') {
2244 for (i=0; i<63; i++) {
2254 if (setjmp(bus_error_jmp) == 0) {
2255 catch_memory_errors = 1;
2257 *vp = kallsyms_lookup_name(tmpstr);
2260 catch_memory_errors = 0;
2262 printf("unknown symbol '%s'\n", tmpstr);
2298 if( '0' <= c && c <= '9' )
2300 if( 'A' <= c && c <= 'F' )
2301 return c - ('A' - 10);
2302 if( 'a' <= c && c <= 'f' )
2303 return c - ('a' - 10);
2308 getstring(char *s, int size)
2319 } while( c != ' ' && c != '\t' && c != '\n' );
2324 static char line[256];
2325 static char *lineptr;
2336 if (lineptr == NULL || *lineptr == 0) {
2337 if (fgets(line, sizeof(line), stdin) == NULL) {
2347 take_input(char *str)
2356 int type = inchar();
2358 static char tmp[64];
2363 xmon_print_symbol(addr, ": ", "\n");
2368 if (setjmp(bus_error_jmp) == 0) {
2369 catch_memory_errors = 1;
2371 addr = kallsyms_lookup_name(tmp);
2373 printf("%s: %lx\n", tmp, addr);
2375 printf("Symbol '%s' not found.\n", tmp);
2378 catch_memory_errors = 0;
2385 /* Print an address in numeric and symbolic form (if possible) */
2386 static void xmon_print_symbol(unsigned long address, const char *mid,
2390 const char *name = NULL;
2391 unsigned long offset, size;
2393 printf("%.16lx", address);
2394 if (setjmp(bus_error_jmp) == 0) {
2395 catch_memory_errors = 1;
2397 name = kallsyms_lookup(address, &size, &offset, &modname,
2400 /* wait a little while to see if we get a machine check */
2404 catch_memory_errors = 0;
2407 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2409 printf(" [%s]", modname);
2411 printf("%s", after);
2414 static void debug_trace(void)
2416 unsigned long val, cmd, on;
2420 /* show current state */
2422 printf("ppc64_debug_switch = 0x%lx\n", ppc64_debug_switch);
2423 for (i = 0; i < PPCDBG_NUM_FLAGS ;i++) {
2424 on = PPCDBG_BITVAL(i) & ppc64_debug_switch;
2425 printf("%02x %s %12s ", i, on ? "on " : "off", trace_names[i] ? trace_names[i] : "");
2426 if (((i+1) % 3) == 0)
2432 while (cmd != '\n') {
2433 on = 1; /* default if no sign given */
2434 while (cmd == '+' || cmd == '-') {
2437 if (cmd == ' ' || cmd == '\n') { /* Turn on or off based on + or - */
2438 ppc64_debug_switch = on ? PPCDBG_ALL:PPCDBG_NONE;
2439 printf("Setting all values to %s...\n", on ? "on" : "off");
2440 if (cmd == '\n') return;
2441 else cmd = skipbl();
2446 termch = cmd; /* not +/- ... let scanhex see it */
2447 scanhex((void *)&val);
2449 printf("Value %x out of range:\n", val);
2453 ppc64_debug_switch |= PPCDBG_BITVAL(val);
2454 printf("enable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
2456 ppc64_debug_switch &= ~PPCDBG_BITVAL(val);
2457 printf("disable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
2463 static void dump_slb(void)
2468 printf("SLB contents of cpu %x\n", smp_processor_id());
2470 for (i = 0; i < SLB_NUM_ENTRIES; i++) {
2471 asm volatile("slbmfee %0,%1" : "=r" (tmp) : "r" (i));
2472 printf("%02d %016lx ", i, tmp);
2474 asm volatile("slbmfev %0,%1" : "=r" (tmp) : "r" (i));
2475 printf("%016lx\n", tmp);
2479 static void dump_stab(void)
2482 unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2484 printf("Segment table contents of cpu %x\n", smp_processor_id());
2486 for (i = 0; i < PAGE_SIZE/16; i++) {
2493 printf("%03d %016lx ", i, a);
2494 printf("%016lx\n", b);
2499 void xmon_init(void)
2502 __debugger_ipi = xmon_ipi;
2503 __debugger_bpt = xmon_bpt;
2504 __debugger_sstep = xmon_sstep;
2505 __debugger_iabr_match = xmon_iabr_match;
2506 __debugger_dabr_match = xmon_dabr_match;
2507 __debugger_fault_handler = xmon_fault_handler;
2510 void dump_segments(void)
2512 if (cpu_has_feature(CPU_FTR_SLB))