13 #include <linux/errno.h>
14 #include <linux/sched.h>
17 #include <linux/reboot.h>
22 #include <linux/export.h>
28 #include <asm/ptrace.h>
29 #include <asm/string.h>
31 #include <asm/machdep.h>
33 #include <asm/processor.h>
34 #include <asm/pgtable.h>
36 #include <asm/mmu_context.h>
37 #include <asm/cputable.h>
40 #include <asm/irq_regs.h>
45 #include <asm/debug.h>
55 #define scanhex xmon_scanhex
56 #define skipbl xmon_skipbl
60 static unsigned long xmon_taken = 1;
69 static unsigned long adrs;
71 #define MAX_DUMP (128 * 1024)
72 static unsigned long ndump = 64;
73 static unsigned long nidump = 16;
74 static unsigned long ncsum = 4096;
76 static char tmpstr[128];
79 static int catch_memory_errors;
80 static long *xmon_fault_jmp[
NR_CPUS];
99 static struct bpt dabr;
100 static struct bpt *iabr;
101 static unsigned bpinstr = 0x7fe00008;
103 #define BP_NUM(bp) ((bp) - bpts + 1)
107 static int mread(
unsigned long,
void *,
int);
108 static int mwrite(
unsigned long,
void *,
int);
109 static int handle_fault(
struct pt_regs *);
110 static void byterev(
unsigned char *,
int);
111 static void memex(
void);
112 static int bsesc(
void);
113 static void dump(
void);
114 static void prdump(
unsigned long,
long);
115 static int ppc_inst_dump(
unsigned long,
long,
int);
116 static void dump_log_buf(
void);
117 static void backtrace(
struct pt_regs *);
118 static void excprint(
struct pt_regs *);
119 static void prregs(
struct pt_regs *);
120 static void memops(
int);
121 static void memlocate(
void);
122 static void memzcan(
void);
123 static void memdiffs(
unsigned char *,
unsigned char *,
unsigned,
unsigned);
125 int scanhex(
unsigned long *valp);
126 static void scannl(
void);
127 static int hexdigit(
int);
129 static void flush_input(
void);
130 static int inchar(
void);
131 static void take_input(
char *);
132 static unsigned long read_spr(
int);
133 static void write_spr(
int,
unsigned long);
134 static void super_regs(
void);
135 static void remove_bpts(
void);
136 static void insert_bpts(
void);
137 static void remove_cpu_bpts(
void);
138 static void insert_cpu_bpts(
void);
139 static struct bpt *at_breakpoint(
unsigned long pc);
140 static struct bpt *in_breakpoint_table(
unsigned long pc,
unsigned long *offp);
141 static int do_step(
struct pt_regs *);
142 static void bpt_cmds(
void);
143 static void cacheflush(
void);
144 static int cpu_cmd(
void);
145 static void csum(
void);
146 static void bootcmds(
void);
147 static void proccall(
void);
149 static void symbol_lookup(
void);
150 static void xmon_show_stack(
unsigned long sp,
unsigned long lr,
152 static void xmon_print_symbol(
unsigned long address,
const char *
mid,
154 static const char *getvecname(
unsigned long vec);
156 static int do_spu_cmd(
void);
159 static void dump_tlb_44x(
void);
161 #ifdef CONFIG_PPC_BOOK3E
162 static void dump_tlb_book3e(
void);
165 static int xmon_no_auto_backtrace;
172 #define REGS_PER_LINE 4
173 #define LAST_VOLATILE 13
176 #define REGS_PER_LINE 8
177 #define LAST_VOLATILE 12
180 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
182 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
183 || ('a' <= (c) && (c) <= 'f') \
184 || ('A' <= (c) && (c) <= 'F'))
185 #define isalnum(c) (('0' <= (c) && (c) <= '9') \
186 || ('a' <= (c) && (c) <= 'z') \
187 || ('A' <= (c) && (c) <= 'Z'))
188 #define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
190 static char *help_string =
"\
192 b show breakpoints\n\
193 bd set data breakpoint\n\
194 bi set instruction breakpoint\n\
195 bc clear breakpoint\n"
198 c print cpus stopped in xmon\n\
199 c# try to switch to cpu number h (in hex)\n"
204 di dump instructions\n\
205 df dump float values\n\
206 dd dump double values\n\
207 dl dump the kernel log buffer\n"
210 dp[#] dump paca for current cpu, or cpu #\n\
211 dpa dump paca for all possible cpus\n"
214 dr dump stream of raw bytes\n\
215 e print exception information\n\
217 la lookup symbol+offset of specified address\n\
218 ls lookup address of specified symbol\n\
219 m examine/change memory\n\
220 mm move a block of memory\n\
221 ms set a block of memory\n\
222 md compare two blocks of memory\n\
223 ml locate a block of memory\n\
224 mz zero a block of memory\n\
225 mi show information about memory allocation\n\
226 p call a procedure\n\
229 #ifdef CONFIG_SPU_BASE
230 " ss stop execution on all spus\n\
231 sr restore execution on stopped spus\n\
232 sf # dump spu fields for spu # (in hex)\n\
233 sd # dump spu local store for spu # (in hex)\n\
234 sdi # disassemble spu local store for spu # (in hex)\n"
236 " S print special registers\n\
238 x exit monitor and recover\n\
239 X exit monitor and dont recover\n"
240 #if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_BOOK3E)
241 " u dump segment table or SLB\n"
242 #elif defined(CONFIG_PPC_STD_MMU_32)
243 " u dump segment registers\n"
244 #elif defined(CONFIG_44x) || defined(CONFIG_PPC_BOOK3E)
252 static struct pt_regs *xmon_regs;
254 static inline void sync(
void)
256 asm volatile(
"sync; isync");
259 static inline void store_inst(
void *
p)
261 asm volatile (
"dcbst 0,%0; sync; icbi 0,%0; isync" : :
"r" (
p));
264 static inline void cflush(
void *
p)
266 asm volatile (
"dcbf 0,%0; icbi 0,%0" : :
"r" (
p));
269 static inline void cinval(
void *
p)
271 asm volatile (
"dcbi 0,%0; icbi 0,%0" : :
"r" (
p));
279 #define SURVEILLANCE_TOKEN 9000
281 static inline void disable_surveillance(
void)
283 #ifdef CONFIG_PPC_PSERIES
285 static struct rtas_args args;
295 if (args.token == RTAS_UNKNOWN_SERVICE)
299 args.rets = &args.args[3];
303 enter_rtas(
__pa(&args));
308 static int xmon_speaker;
310 static void get_output_lock(
void)
313 int last_speaker = 0,
prev;
316 if (xmon_speaker == me)
319 if (xmon_speaker == 0) {
320 last_speaker =
cmpxchg(&xmon_speaker, 0, me);
321 if (last_speaker == 0)
325 while (xmon_speaker == last_speaker) {
330 if (
prev == last_speaker)
337 static void release_output_lock(
void)
342 int cpus_are_in_xmon(
void)
344 return !cpumask_empty(&cpus_in_xmon);
348 static inline int unrecoverable_excp(
struct pt_regs *
regs)
350 #if defined(CONFIG_4xx) || defined(CONFIG_PPC_BOOK3E)
358 static int xmon_core(
struct pt_regs *regs,
int fromipi)
368 unsigned long timeout;
373 bp = in_breakpoint_table(regs->
nip, &offset);
386 printf(
"cpu 0x%x: Exception %lx %s in xmon, "
387 "returning to main loop\n",
388 cpu, regs->
trap, getvecname(
TRAP(regs)));
389 release_output_lock();
390 longjmp(xmon_fault_jmp[cpu], 1);
393 if (
setjmp(recurse_jmp) != 0) {
394 if (!in_xmon || !xmon_gate) {
396 printf(
"xmon: WARNING: bad recursive fault "
397 "on cpu 0x%x\n", cpu);
398 release_output_lock();
401 secondary = !(xmon_taken && cpu ==
xmon_owner);
405 xmon_fault_jmp[
cpu] = recurse_jmp;
406 cpumask_set_cpu(cpu, &cpus_in_xmon);
409 if ((regs->
msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT))
410 bp = at_breakpoint(regs->
nip);
411 if (bp || unrecoverable_excp(regs))
418 printf(
"cpu 0x%x stopped at breakpoint 0x%x (",
420 xmon_print_symbol(regs->
nip,
" ",
")\n");
422 if (unrecoverable_excp(regs))
423 printf(
"WARNING: exception is not recoverable, "
425 release_output_lock();
430 while (secondary && !xmon_gate) {
439 if (!secondary && !xmon_gate) {
447 smp_send_debugger_break();
449 for (timeout = 100000000; timeout != 0; --timeout) {
450 if (cpumask_weight(&cpus_in_xmon) >= ncpus)
456 disable_surveillance();
458 if (bp ||
TRAP(regs) == 0xd00)
459 ppc_inst_dump(regs->
nip, 1, 0);
460 printf(
"enter ? for help\n");
494 cpumask_clear_cpu(cpu, &cpus_in_xmon);
499 printf(
"Exception %lx %s in xmon, returning to main loop\n",
500 regs->
trap, getvecname(
TRAP(regs)));
503 if (
setjmp(recurse_jmp) == 0) {
504 xmon_fault_jmp[0] = recurse_jmp;
508 bp = at_breakpoint(regs->
nip);
511 xmon_print_symbol(regs->
nip,
" ",
")\n");
513 if (unrecoverable_excp(regs))
514 printf(
"WARNING: exception is not recoverable, "
517 disable_surveillance();
519 if (bp ||
TRAP(regs) == 0xd00)
520 ppc_inst_dump(regs->
nip, 1, 0);
521 printf(
"enter ? for help\n");
531 if (regs->
msr & MSR_DE) {
532 bp = at_breakpoint(regs->
nip);
539 if ((regs->
msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
540 bp = at_breakpoint(regs->
nip);
546 }
else if (stepped < 0) {
547 printf(
"Couldn't single-step %s instruction\n",
557 return cmd !=
'X' && cmd !=
EOF;
565 ppc_save_regs(®s);
569 return xmon_core(excp, 0);
577 printf(
"Keyboard interrupt\n");
583 static int xmon_bpt(
struct pt_regs *regs)
588 if ((regs->
msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
592 bp = in_breakpoint_table(regs->
nip, &offset);
593 if (bp !=
NULL && offset == 4) {
600 bp = at_breakpoint(regs->
nip);
609 static int xmon_sstep(
struct pt_regs *regs)
617 static int xmon_dabr_match(
struct pt_regs *regs)
619 if ((regs->
msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
621 if (dabr.enabled == 0)
627 static int xmon_iabr_match(
struct pt_regs *regs)
629 if ((regs->
msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
637 static int xmon_ipi(
struct pt_regs *regs)
646 static int xmon_fault_handler(
struct pt_regs *regs)
651 if (in_xmon && catch_memory_errors)
654 if ((regs->
msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
655 bp = in_breakpoint_table(regs->
nip, &offset);
665 static struct bpt *at_breakpoint(
unsigned long pc)
671 for (i = 0; i <
NBPTS; ++
i, ++bp)
677 static struct bpt *in_breakpoint_table(
unsigned long nip,
unsigned long *offp)
681 off = nip - (
unsigned long) bpts;
682 if (off >=
sizeof(bpts))
684 off %=
sizeof(
struct bpt);
689 return (
struct bpt *) (nip - off);
692 static struct bpt *new_breakpoint(
unsigned long a)
697 bp = at_breakpoint(a);
701 for (bp = bpts; bp < &bpts[
NBPTS]; ++bp) {
704 bp->
instr[1] = bpinstr;
705 store_inst(&bp->
instr[1]);
710 printf(
"Sorry, no free breakpoints. Please clear one first.\n");
714 static void insert_bpts(
void)
720 for (i = 0; i <
NBPTS; ++
i, ++bp) {
724 printf(
"Couldn't read instruction at %lx, "
725 "disabling breakpoint there\n", bp->
address);
730 printf(
"Breakpoint at %lx is on an mtmsrd or rfid "
731 "instruction, disabling it\n", bp->
address);
735 store_inst(&bp->
instr[0]);
739 printf(
"Couldn't write instruction at %lx, "
740 "disabling breakpoint there\n", bp->
address);
744 store_inst((
void *)bp->
address);
748 static void insert_cpu_bpts(
void)
751 set_dabr(dabr.address | (dabr.enabled & 7), DABRX_ALL);
757 static void remove_bpts(
void)
764 for (i = 0; i <
NBPTS; ++
i, ++bp) {
770 printf(
"Couldn't remove breakpoint at %lx\n",
773 store_inst((
void *)bp->
address);
777 static void remove_cpu_bpts(
void)
785 static char *last_cmd;
795 if (!xmon_no_auto_backtrace) {
796 xmon_no_auto_backtrace = 1;
797 xmon_show_stack(excp->
gpr[1], excp->
link, excp->
nip);
809 if (last_cmd ==
NULL)
811 take_input(last_cmd);
860 if (do_spu_cmd() == 0)
869 printf(
" <no input ...>\n");
891 #ifdef CONFIG_PPC_STD_MMU
895 #elif defined(CONFIG_4xx)
899 #elif defined(CONFIG_PPC_BOOK3E)
905 printf(
"Unrecognized command: ");
907 if (
' ' < cmd && cmd <=
'~')
912 }
while (cmd !=
'\n');
913 printf(
" (type ? for help)\n");
920 static int do_step(
struct pt_regs *regs)
923 mtspr(SPRN_DBCR0,
mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
931 static int do_step(
struct pt_regs *regs)
937 if ((regs->
msr & (MSR_64BIT|MSR_PR|MSR_IR)) == (MSR_64BIT|MSR_IR)) {
938 if (
mread(regs->
nip, &instr, 4) == 4) {
941 printf(
"Couldn't single-step %s instruction\n",
942 (
IS_RFID(instr)?
"rfid":
"mtmsrd"));
946 regs->
trap = 0xd00 | (regs->
trap & 1);
948 xmon_print_symbol(regs->
nip,
" ",
"\n");
949 ppc_inst_dump(regs->
nip, 1, 0);
959 static void bootcmds(
void)
972 static int cpu_cmd(
void)
1001 printf(
"cpu 0x%x isn't in xmon\n", cpu);
1008 while (!xmon_taken) {
1009 if (--timeout == 0) {
1015 printf(
"cpu %u didn't take control\n", cpu);
1026 static unsigned short fcstab[256] = {
1027 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
1028 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
1029 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
1030 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1031 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1032 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1033 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1034 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1035 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1036 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1037 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1038 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1039 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1040 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1041 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1042 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1043 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1044 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1045 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1046 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1047 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1048 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1049 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1050 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1051 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1052 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1053 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1054 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1055 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1056 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1057 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1058 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1061 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1075 for (i = 0; i < ncsum; ++
i) {
1076 if (
mread(adrs+i, &v, 1) == 0) {
1077 printf(
"csum stopped at %x\n", adrs+i);
1088 static long check_bp_loc(
unsigned long addr)
1094 printf(
"Breakpoints may only be placed at kernel addresses\n");
1097 if (!
mread(addr, &instr,
sizeof(instr))) {
1098 printf(
"Can't read instruction at address %lx\n", addr);
1102 printf(
"Breakpoints may not be placed on mtmsrd or rfid "
1109 static char *breakpoint_help_string =
1110 "Breakpoint command usage:\n"
1111 "b show breakpoints\n"
1112 "b <addr> [cnt] set breakpoint at given instr addr\n"
1113 "bc clear all breakpoints\n"
1114 "bc <n/addr> clear breakpoint number n or at addr\n"
1115 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1116 "bd <addr> [cnt] set hardware data breakpoint\n"
1126 const char badaddr[] =
"Only kernel addresses are permitted "
1127 "for breakpoints\n";
1137 else if (cmd ==
'w')
1149 dabr.enabled = mode |
BP_DABR;
1155 printf(
"Hardware instruction breakpoint "
1156 "not supported on this cpu\n");
1165 if (!check_bp_loc(a))
1167 bp = new_breakpoint(a);
1178 for (i = 0; i <
NBPTS; ++
i)
1182 printf(
"All breakpoints cleared\n");
1186 if (a <= NBPTS && a >= 1) {
1191 bp = at_breakpoint(a);
1193 printf(
"No breakpoint at %x\n", a);
1199 xmon_print_symbol(bp->
address,
" ",
")\n");
1207 printf(breakpoint_help_string);
1213 printf(
" type address\n");
1216 if (dabr.enabled & 1)
1218 if (dabr.enabled & 2)
1222 for (bp = bpts; bp < &bpts[
NBPTS]; ++bp) {
1227 xmon_print_symbol(bp->
address,
" ",
"\n");
1232 if (!check_bp_loc(a))
1234 bp = new_breakpoint(a);
1243 const char *getvecname(
unsigned long vec)
1248 case 0x100: ret =
"(System Reset)";
break;
1249 case 0x200: ret =
"(Machine Check)";
break;
1250 case 0x300: ret =
"(Data Access)";
break;
1251 case 0x380: ret =
"(Data SLB Access)";
break;
1252 case 0x400: ret =
"(Instruction Access)";
break;
1253 case 0x480: ret =
"(Instruction SLB Access)";
break;
1254 case 0x500: ret =
"(Hardware Interrupt)";
break;
1255 case 0x600: ret =
"(Alignment)";
break;
1256 case 0x700: ret =
"(Program Check)";
break;
1257 case 0x800: ret =
"(FPU Unavailable)";
break;
1258 case 0x900: ret =
"(Decrementer)";
break;
1259 case 0xc00: ret =
"(System Call)";
break;
1260 case 0xd00: ret =
"(Single Step)";
break;
1261 case 0xf00: ret =
"(Performance Monitor)";
break;
1262 case 0xf20: ret =
"(Altivec Unavailable)";
break;
1263 case 0x1300: ret =
"(Instruction Breakpoint)";
break;
1269 static void get_function_bounds(
unsigned long pc,
unsigned long *startp,
1270 unsigned long *endp)
1275 *startp = *endp = 0;
1278 if (
setjmp(bus_error_jmp) == 0) {
1279 catch_memory_errors = 1;
1284 *endp = pc - offset +
size;
1288 catch_memory_errors = 0;
1291 static int xmon_depth_to_print = 64;
1293 #define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1294 #define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long))
1296 #ifdef __powerpc64__
1297 #define REGS_OFFSET 0x70
1299 #define REGS_OFFSET 16
1302 static void xmon_show_stack(
unsigned long sp,
unsigned long lr,
1306 unsigned long newsp;
1314 printf(
"SP (%lx) is in userspace\n", sp);
1319 || !
mread(sp, &newsp,
sizeof(
unsigned long))) {
1320 printf(
"Couldn't read stack frame at %lx\n", sp);
1329 if ((pc | lr) != 0) {
1330 unsigned long fnstart, fnend;
1331 unsigned long nextip;
1334 get_function_bounds(pc, &fnstart, &fnend);
1338 sizeof(
unsigned long));
1341 || (fnstart <= lr && lr < fnend))
1343 }
else if (lr == nextip) {
1346 && !(fnstart <= lr && lr < fnend)) {
1347 printf(
"[link register ] ");
1348 xmon_print_symbol(lr,
" ",
"\n");
1352 xmon_print_symbol(ip,
" ",
" (unreliable)\n");
1358 xmon_print_symbol(ip,
" ",
"\n");
1367 printf(
"Couldn't read registers at %lx\n",
1371 printf(
"--- Exception: %lx %s at ", regs.
trap,
1372 getvecname(
TRAP(®s)));
1375 xmon_print_symbol(pc,
" ",
"\n");
1382 }
while (count++ < xmon_depth_to_print);
1385 static void backtrace(
struct pt_regs *excp)
1390 xmon_show_stack(sp, 0, 0);
1392 xmon_show_stack(excp->
gpr[1], excp->
link, excp->
nip);
1396 static void print_bug_trap(
struct pt_regs *regs)
1399 const struct bug_entry *bug;
1402 if (regs->
msr & MSR_PR)
1410 if (is_warning_bug(bug))
1413 #ifdef CONFIG_DEBUG_BUGVERBOSE
1414 printf(
"kernel BUG at %s:%u!\n",
1415 bug->file, bug->line);
1417 printf(
"kernel BUG at %p!\n", (
void *)bug->bug_addr);
1422 static void excprint(
struct pt_regs *
fp)
1431 printf(
"Vector: %lx %s at [%lx]\n", fp->
trap, getvecname(trap), fp);
1433 xmon_print_symbol(fp->
nip,
": ",
"\n");
1436 xmon_print_symbol(fp->
link,
": ",
"\n");
1441 if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1449 printf(
" paca = 0x%lx\t softe: %d\t irq_happened: 0x%02x\n",
1450 local_paca, local_paca->soft_enabled, local_paca->irq_happened);
1453 printf(
" pid = %ld, comm = %s\n",
1461 static void prregs(
struct pt_regs *fp)
1468 if (
setjmp(bus_error_jmp) == 0) {
1469 catch_memory_errors = 1;
1471 regs = *(
struct pt_regs *)base;
1475 catch_memory_errors = 0;
1476 printf(
"*** Error reading registers from "REG"\n",
1480 catch_memory_errors = 0;
1486 for (n = 0; n < 16; ++
n)
1488 n, fp->
gpr[n], n+16, fp->
gpr[n+16]);
1490 for (n = 0; n < 7; ++
n)
1492 n, fp->
gpr[n], n+7, fp->
gpr[n+7]);
1495 for (n = 0; n < 32; ++
n) {
1497 (n & 3) == 3?
"\n":
" ");
1505 xmon_print_symbol(fp->
nip,
" ",
"\n");
1508 xmon_print_symbol(fp->
orig_gpr3,
" ",
"\n");
1511 xmon_print_symbol(fp->
link,
" ",
"\n");
1516 if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1520 static void cacheflush(
void)
1523 unsigned long nflush;
1534 if (
setjmp(bus_error_jmp) == 0) {
1535 catch_memory_errors = 1;
1540 cflush((
void *) adrs);
1543 cinval((
void *) adrs);
1549 catch_memory_errors = 0;
1552 static unsigned long
1555 unsigned int instrs[2];
1557 unsigned long ret = -1
UL;
1559 unsigned long opd[3];
1561 opd[0] = (
unsigned long)instrs;
1570 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1571 instrs[1] = 0x4e800020;
1573 store_inst(instrs+1);
1575 if (
setjmp(bus_error_jmp) == 0) {
1576 catch_memory_errors = 1;
1591 write_spr(
int n,
unsigned long val)
1593 unsigned int instrs[2];
1596 unsigned long opd[3];
1598 opd[0] = (
unsigned long)instrs;
1606 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1607 instrs[1] = 0x4e800020;
1609 store_inst(instrs+1);
1611 if (
setjmp(bus_error_jmp) == 0) {
1612 catch_memory_errors = 1;
1624 static unsigned long regno;
1628 static void super_regs(
void)
1635 unsigned long sp, toc;
1636 asm(
"mr %0,1" :
"=r" (
sp) :);
1637 asm(
"mr %0,2" :
"=r" (toc) :);
1640 mfmsr(),
mfspr(SPRN_SPRG0));
1641 printf(
"pvr = "REG
" sprg1= "REG
"\n",
1643 printf(
"dec = "REG
" sprg2= "REG
"\n",
1645 printf(
"sp = "REG
" sprg3= "REG
"\n", sp,
mfspr(SPRN_SPRG3));
1646 printf(
"toc = "REG
" dar = "REG
"\n", toc,
mfspr(SPRN_DAR));
1654 val = read_spr(regno);
1656 write_spr(regno, val);
1659 printf(
"spr %lx = %lx\n", regno, read_spr(regno));
1669 mread(
unsigned long adrs,
void *
buf,
int size)
1675 if (
setjmp(bus_error_jmp) == 0) {
1676 catch_memory_errors = 1;
1691 for( ; n <
size; ++
n) {
1701 catch_memory_errors = 0;
1706 mwrite(
unsigned long adrs,
void *buf,
int size)
1712 if (
setjmp(bus_error_jmp) == 0) {
1713 catch_memory_errors = 1;
1728 for ( ; n <
size; ++
n) {
1738 printf(
"*** Error writing address %x\n", adrs + n);
1740 catch_memory_errors = 0;
1744 static int fault_type;
1745 static int fault_except;
1746 static char *fault_chars[] = {
"--",
"**",
"##" };
1748 static int handle_fault(
struct pt_regs *regs)
1750 fault_except =
TRAP(regs);
1751 switch (
TRAP(regs)) {
1768 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1771 byterev(
unsigned char *val,
int size)
1777 SWAP(val[0], val[1], t);
1780 SWAP(val[0], val[3], t);
1781 SWAP(val[1], val[2], t);
1784 SWAP(val[0], val[7], t);
1785 SWAP(val[1], val[6], t);
1786 SWAP(val[2], val[5], t);
1787 SWAP(val[3], val[4], t);
1795 static char *memex_help_string =
1796 "Memory examine command usage:\n"
1797 "m [addr] [flags] examine/change memory\n"
1798 " addr is optional. will start where left off.\n"
1799 " flags may include chars from this set:\n"
1800 " b modify by bytes (default)\n"
1801 " w modify by words (2 byte)\n"
1802 " l modify by longs (4 byte)\n"
1803 " d modify by doubleword (8 byte)\n"
1804 " r toggle reverse byte order mode\n"
1805 " n do not read memory (for i/o spaces)\n"
1806 " . ok to read (default)\n"
1807 "NOTE: flags are saved as defaults\n"
1810 static char *memex_subcmd_help_string =
1811 "Memory examine subcommands:\n"
1812 " hexval write this val to current location\n"
1813 " 'string' write chars from string to this location\n"
1814 " ' increment address\n"
1815 " ^ decrement address\n"
1816 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1817 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1818 " ` clear no-read flag\n"
1819 " ; stay at this addr\n"
1820 " v change to byte mode\n"
1821 " w change to word (2 byte) mode\n"
1822 " l change to long (4 byte) mode\n"
1823 " u change to doubleword (8 byte) mode\n"
1824 " m addr change current addr\n"
1825 " n toggle no-read flag\n"
1826 " r toggle byte reverse flag\n"
1827 " < count back up count bytes\n"
1828 " > count skip forward count bytes\n"
1829 " x exit this mode\n"
1837 unsigned char val[16];
1842 printf(memex_help_string);
1848 while ((cmd =
skipbl()) !=
'\n') {
1850 case 'b': size = 1;
break;
1851 case 'w': size = 2;
break;
1852 case 'l': size = 4;
break;
1853 case 'd': size = 8;
break;
1854 case 'r': brev = !brev;
break;
1855 case 'n': mnoread = 1;
break;
1856 case '.': mnoread = 0;
break;
1865 n =
mread(adrs, val, size);
1866 printf(REG
"%c", adrs, brev?
'r':
' ');
1871 for (i = 0; i <
n; ++
i)
1873 for (; i <
size; ++
i)
1874 printf(
"%s", fault_chars[fault_type]);
1881 for (i = 0; i <
size; ++
i)
1882 val[i] = n >> (i * 8);
1898 else if( n ==
'\'' )
1900 for (i = 0; i <
size; ++
i)
1901 val[i] = n >> (i * 8);
1941 adrs -= 1 << nslash;
1945 adrs += 1 << nslash;
1949 adrs += 1 << -nslash;
1953 adrs -= 1 << -nslash;
1975 printf(memex_subcmd_help_string);
1990 case 'n': c =
'\n';
break;
1991 case 'r': c =
'\r';
break;
1992 case 'b': c =
'\b';
break;
1993 case 't': c =
'\t';
break;
1998 static void xmon_rawdump (
unsigned long adrs,
long ndump)
2001 unsigned char temp[16];
2003 for (n = ndump; n > 0;) {
2005 nr =
mread(adrs, temp, r);
2007 for (m = 0; m <
r; ++
m) {
2011 printf(
"%s", fault_chars[fault_type]);
2021 static void dump_one_paca(
int cpu)
2023 struct paca_struct *
p;
2025 if (
setjmp(bus_error_jmp) != 0) {
2026 printf(
"*** Error dumping paca for cpu 0x%x!\n", cpu);
2030 catch_memory_errors = 1;
2035 printf(
"paca for cpu 0x%x @ %p:\n", cpu, p);
2041 #define DUMP(paca, name, format) \
2042 printf(" %-*s = %#-*"format"\t(0x%lx)\n", 16, #name, 18, paca->name, \
2043 offsetof(struct paca_struct, name));
2045 DUMP(p, lock_token,
"x");
2046 DUMP(p, paca_index,
"x");
2047 DUMP(p, kernel_toc,
"lx");
2048 DUMP(p, kernelbase,
"lx");
2049 DUMP(p, kernel_msr,
"lx");
2050 #ifdef CONFIG_PPC_STD_MMU_64
2051 DUMP(p, stab_real,
"lx");
2052 DUMP(p, stab_addr,
"lx");
2054 DUMP(p, emergency_sp,
"p");
2056 DUMP(p, hw_cpu_id,
"x");
2057 DUMP(p, cpu_start,
"x");
2058 DUMP(p, kexec_state,
"x");
2060 DUMP(p, kstack,
"lx");
2061 DUMP(p, stab_rr,
"lx");
2062 DUMP(p, saved_r1,
"lx");
2063 DUMP(p, trap_save,
"x");
2064 DUMP(p, soft_enabled,
"x");
2065 DUMP(p, irq_happened,
"x");
2066 DUMP(p, io_sync,
"x");
2067 DUMP(p, irq_work_pending,
"x");
2068 DUMP(p, nap_state_lost,
"x");
2072 catch_memory_errors = 0;
2076 static void dump_all_pacas(
void)
2081 printf(
"No possible cpus, use 'dp #' to dump individual cpus\n");
2089 static
void dump_pacas(
void)
2109 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
2110 || ('a' <= (c) && (c) <= 'f') \
2111 || ('A' <= (c) && (c) <= 'F'))
2126 if ((
isxdigit(c) && c !=
'f' && c !=
'd') || c ==
'\n')
2137 adrs += ppc_inst_dump(adrs, nidump, 1);
2139 }
else if (c ==
'l') {
2141 }
else if (c ==
'r') {
2145 xmon_rawdump(adrs, ndump);
2154 prdump(adrs, ndump);
2161 prdump(
unsigned long adrs,
long ndump)
2164 unsigned char temp[16];
2166 for (n = ndump; n > 0;) {
2170 nr =
mread(adrs, temp, r);
2172 for (m = 0; m <
r; ++
m) {
2173 if ((m & (
sizeof(
long) - 1)) == 0 && m > 0)
2178 printf(
"%s", fault_chars[fault_type]);
2180 for (; m < 16; ++
m) {
2181 if ((m & (
sizeof(
long) - 1)) == 0)
2186 for (m = 0; m <
r; ++
m) {
2189 putchar(
' ' <= c && c <=
'~'? c:
'.');
2205 generic_inst_dump(
unsigned long adr,
long count,
int praddr,
2209 unsigned long first_adr;
2210 unsigned long inst, last_inst = 0;
2211 unsigned char val[4];
2214 for (first_adr = adr; count > 0; --
count, adr += 4) {
2215 nr =
mread(adr, val, 4);
2218 const char *
x = fault_chars[fault_type];
2219 printf(REG
" %s%s%s%s\n", adr, x, x, x, x);
2224 if (adr > first_adr && inst == last_inst) {
2234 printf(REG
" %.8x", adr, inst);
2236 dump_func(inst, adr);
2239 return adr - first_adr;
2243 ppc_inst_dump(
unsigned long adr,
long count,
int praddr)
2251 xmon_print_symbol(addr,
"\t# ",
"");
2258 unsigned char buf[128];
2261 if (
setjmp(bus_error_jmp) != 0) {
2262 printf(
"Error dumping printk buffer!\n");
2266 catch_memory_errors = 1;
2269 kmsg_dump_rewind_nolock(&dumper);
2270 while (kmsg_dump_get_line_nolock(&dumper,
false, buf,
sizeof(buf), &len)) {
2278 catch_memory_errors = 0;
2284 static unsigned long mdest;
2285 static unsigned long msrc;
2286 static unsigned long mval;
2287 static unsigned long mcount;
2288 static unsigned long mdiffs;
2294 if( termch !=
'\n' )
2296 scanhex((
void *)(cmd ==
's'? &mval: &msrc));
2297 if( termch !=
'\n' )
2302 memmove((
void *)mdest, (
void *)msrc, mcount);
2305 memset((
void *)mdest, mval, mcount);
2308 if( termch !=
'\n' )
2311 memdiffs((
unsigned char *)mdest, (
unsigned char *)msrc, mcount, mdiffs);
2317 memdiffs(
unsigned char *
p1,
unsigned char *p2,
unsigned nb,
unsigned maxpr)
2322 for( n = nb; n > 0; --
n )
2323 if( *p1++ != *p2++ )
2324 if( ++prt <= maxpr )
2325 printf(
"%.16x %.2x # %.16x %.2x\n", p1 - 1,
2326 p1[-1], p2 - 1, p2[-1]);
2328 printf(
"Total of %d differences\n", prt);
2331 static unsigned mend;
2332 static unsigned mask;
2338 unsigned char val[4];
2342 if (termch !=
'\n') {
2345 if (termch !=
'\n') {
2349 if (termch !=
'\n') termch = 0;
2354 for (a = mdest; a < mend; a += 4) {
2355 if (
mread(a, val, 4) == 4
2356 && ((
GETWORD(val) ^ mval) & mask) == 0) {
2364 static unsigned long mskip = 0x1000;
2365 static unsigned long mlim = 0xffffffff;
2375 if (termch !=
'\n') termch = 0;
2377 if (termch !=
'\n') termch = 0;
2380 for (a = mdest; a < mlim; a += mskip) {
2381 ok =
mread(a, &v, 1);
2384 }
else if (!ok && ook)
2385 printf(
"%.8x\n", a - mskip);
2391 printf(
"%.8x\n", a - mskip);
2394 static void proccall(
void)
2396 unsigned long args[8];
2399 typedef unsigned long (*callfunc_t)(
unsigned long,
unsigned long,
2408 for (i = 0; i < 8; ++
i)
2410 for (i = 0; i < 8; ++
i) {
2411 if (!
scanhex(&args[i]) || termch ==
'\n')
2415 func = (callfunc_t) adrs;
2417 if (
setjmp(bus_error_jmp) == 0) {
2418 catch_memory_errors = 1;
2420 ret =
func(args[0], args[1], args[2], args[3],
2421 args[4], args[5], args[6], args[7]);
2423 printf(
"return value is %x\n", ret);
2425 printf(
"*** %x exception occurred\n", fault_except);
2427 catch_memory_errors = 0;
2441 while( c ==
' ' || c ==
'\t' )
2448 "r0",
"r1",
"r2",
"r3",
"r4",
"r5",
"r6",
"r7",
2449 "r8",
"r9",
"r10",
"r11",
"r12",
"r13",
"r14",
"r15",
2450 "r16",
"r17",
"r18",
"r19",
"r20",
"r21",
"r22",
"r23",
2451 "r24",
"r25",
"r26",
"r27",
"r28",
"r29",
"r30",
"r31",
2452 "pc",
"msr",
"or3",
"ctr",
"lr",
"xer",
"ccr",
2458 "trap",
"dar",
"dsisr",
"res"
2473 for (i = 0; i <
sizeof(regname) - 1; ++
i) {
2483 if (
strcmp(regnames[i], regname) == 0) {
2484 if (xmon_regs ==
NULL) {
2485 printf(
"regs not available\n");
2488 *vp = ((
unsigned long *)xmon_regs)[
i];
2492 printf(
"invalid register name '%%%s'\n", regname);
2510 }
else if (c ==
'$') {
2512 for (i=0; i<63; i++) {
2522 if (
setjmp(bus_error_jmp) == 0) {
2523 catch_memory_errors = 1;
2528 catch_memory_errors = 0;
2530 printf(
"unknown symbol '%s'\n", tmpstr);
2563 static int hexdigit(
int c)
2565 if(
'0' <= c && c <=
'9' )
2567 if(
'A' <= c && c <=
'F' )
2568 return c - (
'A' - 10);
2569 if(
'a' <= c && c <=
'f' )
2570 return c - (
'a' - 10);
2586 }
while( c !=
' ' && c !=
'\t' && c !=
'\n' );
2591 static char line[256];
2592 static char *lineptr;
2603 if (lineptr ==
NULL || *lineptr == 0) {
2614 take_input(
char *
str)
2623 int type = inchar();
2625 static char tmp[64];
2630 xmon_print_symbol(addr,
": ",
"\n");
2635 if (
setjmp(bus_error_jmp) == 0) {
2636 catch_memory_errors = 1;
2640 printf(
"%s: %lx\n", tmp, addr);
2642 printf(
"Symbol '%s' not found.\n", tmp);
2645 catch_memory_errors = 0;
2653 static void xmon_print_symbol(
unsigned long address,
const char *
mid,
2657 const char *name =
NULL;
2661 if (
setjmp(bus_error_jmp) == 0) {
2662 catch_memory_errors = 1;
2671 catch_memory_errors = 0;
2674 printf(
"%s%s+%#lx/%#lx", mid, name, offset, size);
2676 printf(
" [%s]", modname);
2681 #ifdef CONFIG_PPC_BOOK3S_64
2682 static void dump_slb(
void)
2691 asm volatile(
"slbmfee %0,%1" :
"=r" (
esid) :
"r" (i));
2692 asm volatile(
"slbmfev %0,%1" :
"=r" (vsid) :
"r" (i));
2694 if (valid | esid | vsid) {
2695 printf(
"%02d %016lx %016lx", i, esid, vsid);
2699 printf(
" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
2704 printf(
" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
2715 static void dump_stab(
void)
2718 unsigned long *tmp = (
unsigned long *)local_paca->stab_addr;
2729 printf(
"%03d %016lx ", i, a);
2737 if (mmu_has_feature(MMU_FTR_SLB))
2744 #ifdef CONFIG_PPC_STD_MMU_32
2750 for (i = 0; i < 16; ++
i)
2751 printf(
" %x", mfsrin(i));
2757 static void dump_tlb_44x(
void)
2763 asm volatile(
"tlbre %0,%1,0" :
"=r" (
w0) :
"r" (i));
2764 asm volatile(
"tlbre %0,%1,1" :
"=r" (
w1) :
"r" (i));
2765 asm volatile(
"tlbre %0,%1,2" :
"=r" (
w2) :
"r" (i));
2766 printf(
"[%02x] %08x %08x %08x ", i, w0, w1, w2);
2768 printf(
"V %08x -> %01x%08x %c%c%c%c%c",
2783 #ifdef CONFIG_PPC_BOOK3E
2784 static void dump_tlb_book3e(
void)
2786 u32 mmucfg, pidmask, lpidmask;
2788 int i, tlb, ntlbs, pidsz, lpidsz, rasz, lrat = 0;
2790 static const char *pgsz_names[] = {
2826 mmucfg =
mfspr(SPRN_MMUCFG);
2827 mmu_version = (mmucfg & 3) + 1;
2828 ntlbs = ((mmucfg >> 2) & 3) + 1;
2829 pidsz = ((mmucfg >> 6) & 0x1f) + 1;
2830 lpidsz = (mmucfg >> 24) & 0xf;
2831 rasz = (mmucfg >> 16) & 0x7f;
2832 if ((mmu_version > 1) && (mmucfg & 0x10000))
2834 printf(
"Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n",
2835 mmu_version, ntlbs, pidsz, lpidsz, rasz);
2836 pidmask = (1ul << pidsz) - 1;
2837 lpidmask = (1ul << lpidsz) - 1;
2838 ramask = (1ull << rasz) - 1;
2840 for (tlb = 0; tlb < ntlbs; tlb++) {
2842 int nent, assoc, new_cc = 1;
2843 printf(
"TLB %d:\n------\n", tlb);
2846 tlbcfg =
mfspr(SPRN_TLB0CFG);
2849 tlbcfg =
mfspr(SPRN_TLB1CFG);
2852 tlbcfg =
mfspr(SPRN_TLB2CFG);
2855 tlbcfg =
mfspr(SPRN_TLB3CFG);
2858 printf(
"Unsupported TLB number !\n");
2861 nent = tlbcfg & 0xfff;
2862 assoc = (tlbcfg >> 24) & 0xff;
2863 for (i = 0; i < nent; i++) {
2868 int esel =
i,
cc =
i;
2877 mtspr(SPRN_MAS0, mas0);
2878 mtspr(SPRN_MAS1, mas1);
2879 mtspr(SPRN_MAS2, mas2);
2880 asm volatile(
"tlbre 0,0,0" : : :
"memory");
2881 mas1 =
mfspr(SPRN_MAS1);
2882 mas2 =
mfspr(SPRN_MAS2);
2883 mas7_mas3 =
mfspr(SPRN_MAS7_MAS3);
2884 if (assoc && (i % assoc) == 0)
2891 printf(
"%04x-%c", cc,
'A' + esel);
2893 printf(
" |%c",
'A' + esel);
2895 printf(
" %016llx %04x %s %c%c AS%c",
2897 (mas1 >> 16) & 0x3fff,
2898 pgsz_names[(mas1 >> 7) & 0x1f],
2902 printf(
" %c%c%c%c%c%c%c",
2905 mas2 &
MAS2_W ?
'w' :
' ',
2906 mas2 &
MAS2_I ?
'i' :
' ',
2907 mas2 &
MAS2_M ?
'm' :
' ',
2908 mas2 &
MAS2_G ?
'g' :
' ',
2909 mas2 &
MAS2_E ?
'e' :
' ');
2910 printf(
" %016llx", mas7_mas3 & ramask & ~0x7ffull);
2913 pgsz_names[(mas7_mas3 >> 1) & 0x1f]);
2915 printf(
" U%c%c%c S%c%c%c\n",
2916 mas7_mas3 &
MAS3_UX ?
'x' :
' ',
2917 mas7_mas3 &
MAS3_UW ?
'w' :
' ',
2918 mas7_mas3 &
MAS3_UR ?
'r' :
' ',
2919 mas7_mas3 &
MAS3_SX ?
'x' :
' ',
2920 mas7_mas3 &
MAS3_SW ?
'w' :
' ',
2921 mas7_mas3 &
MAS3_SR ?
'r' :
' ');
2927 static void xmon_init(
int enable)
2931 __debugger_ipi = xmon_ipi;
2932 __debugger_bpt = xmon_bpt;
2933 __debugger_sstep = xmon_sstep;
2934 __debugger_iabr_match = xmon_iabr_match;
2935 __debugger_dabr_match = xmon_dabr_match;
2936 __debugger_fault_handler = xmon_fault_handler;
2939 __debugger_ipi =
NULL;
2940 __debugger_bpt =
NULL;
2941 __debugger_sstep =
NULL;
2942 __debugger_iabr_match =
NULL;
2943 __debugger_dabr_match =
NULL;
2944 __debugger_fault_handler =
NULL;
2949 #ifdef CONFIG_MAGIC_SYSRQ
2950 static void sysrq_handle_xmon(
int key)
2960 .action_msg =
"Entering xmon",
2963 static int __init setup_xmon_sysrq(
void)
2973 static int __init early_parse_xmon(
char *p)
2975 if (!p ||
strncmp(p,
"early", 5) == 0) {
2979 }
else if (
strncmp(p,
"on", 2) == 0)
2981 else if (
strncmp(p,
"off", 3) == 0)
2983 else if (
strncmp(p,
"nobt", 4) == 0)
2984 xmon_no_auto_backtrace = 1;
2994 #ifdef CONFIG_XMON_DEFAULT
3002 #ifdef CONFIG_SPU_BASE
3006 u64 saved_mfc_sr1_RW;
3007 u32 saved_spu_runcntl_RW;
3008 unsigned long dump_addr;
3012 #define XMON_NUM_SPUS 16
3014 static struct spu_info spu_info[XMON_NUM_SPUS];
3021 if (spu->number >= XMON_NUM_SPUS) {
3026 spu_info[spu->number].spu = spu;
3027 spu_info[spu->number].stopped_ok = 0;
3028 spu_info[spu->number].dump_addr = (
unsigned long)
3029 spu_info[spu->number].spu->local_store;
3033 static void stop_spus(
void)
3039 for (i = 0; i < XMON_NUM_SPUS; i++) {
3040 if (!spu_info[i].spu)
3043 if (
setjmp(bus_error_jmp) == 0) {
3044 catch_memory_errors = 1;
3047 spu = spu_info[
i].spu;
3049 spu_info[
i].saved_spu_runcntl_RW =
3050 in_be32(&spu->problem->spu_runcntl_RW);
3052 tmp = spu_mfc_sr1_get(spu);
3053 spu_info[
i].saved_mfc_sr1_RW =
tmp;
3055 tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
3056 spu_mfc_sr1_set(spu, tmp);
3061 spu_info[
i].stopped_ok = 1;
3063 printf(
"Stopped spu %.2d (was %s)\n", i,
3064 spu_info[i].saved_spu_runcntl_RW ?
3065 "running" :
"stopped");
3067 catch_memory_errors = 0;
3068 printf(
"*** Error stopping spu %.2d\n", i);
3070 catch_memory_errors = 0;
3074 static void restart_spus(
void)
3079 for (i = 0; i < XMON_NUM_SPUS; i++) {
3080 if (!spu_info[i].spu)
3083 if (!spu_info[i].stopped_ok) {
3084 printf(
"*** Error, spu %d was not successfully stopped"
3085 ", not restarting\n", i);
3089 if (
setjmp(bus_error_jmp) == 0) {
3090 catch_memory_errors = 1;
3093 spu = spu_info[
i].spu;
3094 spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
3095 out_be32(&spu->problem->spu_runcntl_RW,
3096 spu_info[i].saved_spu_runcntl_RW);
3101 printf(
"Restarted spu %.2d\n", i);
3103 catch_memory_errors = 0;
3104 printf(
"*** Error restarting spu %.2d\n", i);
3106 catch_memory_errors = 0;
3110 #define DUMP_WIDTH 23
3111 #define DUMP_VALUE(format, field, value) \
3113 if (setjmp(bus_error_jmp) == 0) { \
3114 catch_memory_errors = 1; \
3116 printf(" %-*s = "format"\n", DUMP_WIDTH, \
3121 catch_memory_errors = 0; \
3122 printf(" %-*s = *** Error reading field.\n", \
3123 DUMP_WIDTH, #field); \
3125 catch_memory_errors = 0; \
3128 #define DUMP_FIELD(obj, format, field) \
3129 DUMP_VALUE(format, field, obj->field)
3131 static void dump_spu_fields(
struct spu *spu)
3133 printf(
"Dumping spu fields at address %p:\n", spu);
3135 DUMP_FIELD(spu,
"0x%x", number);
3136 DUMP_FIELD(spu,
"%s", name);
3137 DUMP_FIELD(spu,
"0x%lx", local_store_phys);
3138 DUMP_FIELD(spu,
"0x%p", local_store);
3139 DUMP_FIELD(spu,
"0x%lx", ls_size);
3140 DUMP_FIELD(spu,
"0x%x",
node);
3141 DUMP_FIELD(spu,
"0x%lx", flags);
3142 DUMP_FIELD(spu,
"%d", class_0_pending);
3143 DUMP_FIELD(spu,
"0x%lx", class_0_dar);
3144 DUMP_FIELD(spu,
"0x%lx", class_1_dar);
3145 DUMP_FIELD(spu,
"0x%lx", class_1_dsisr);
3146 DUMP_FIELD(spu,
"0x%lx", irqs[0]);
3147 DUMP_FIELD(spu,
"0x%lx", irqs[1]);
3148 DUMP_FIELD(spu,
"0x%lx", irqs[2]);
3149 DUMP_FIELD(spu,
"0x%x", slb_replace);
3150 DUMP_FIELD(spu,
"%d",
pid);
3151 DUMP_FIELD(spu,
"0x%p", mm);
3152 DUMP_FIELD(spu,
"0x%p",
ctx);
3153 DUMP_FIELD(spu,
"0x%p",
rq);
3155 DUMP_FIELD(spu,
"0x%lx", problem_phys);
3156 DUMP_FIELD(spu,
"0x%p", problem);
3157 DUMP_VALUE(
"0x%x", problem->spu_runcntl_RW,
3158 in_be32(&spu->problem->spu_runcntl_RW));
3159 DUMP_VALUE(
"0x%x", problem->spu_status_R,
3160 in_be32(&spu->problem->spu_status_R));
3161 DUMP_VALUE(
"0x%x", problem->spu_npc_RW,
3162 in_be32(&spu->problem->spu_npc_RW));
3163 DUMP_FIELD(spu,
"0x%p", priv2);
3164 DUMP_FIELD(spu,
"0x%p",
pdata);
3168 spu_inst_dump(
unsigned long adr,
long count,
int praddr)
3173 static void dump_spu_ls(
unsigned long num,
int subcmd)
3177 if (
setjmp(bus_error_jmp) == 0) {
3178 catch_memory_errors = 1;
3180 ls_addr = (
unsigned long)spu_info[num].spu->local_store;
3184 catch_memory_errors = 0;
3185 printf(
"*** Error: accessing spu info for spu %d\n", num);
3188 catch_memory_errors = 0;
3193 addr = spu_info[num].dump_addr;
3195 if (addr >= ls_addr +
LS_SIZE) {
3196 printf(
"*** Error: address outside of local store\n");
3202 addr += spu_inst_dump(addr, 16, 1);
3212 spu_info[num].dump_addr =
addr;
3215 static int do_spu_cmd(
void)
3217 static unsigned long num = 0;
3218 int cmd, subcmd = 0;
3230 if (
isxdigit(subcmd) || subcmd ==
'\n')
3234 if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
3235 printf(
"*** Error: invalid spu number\n");
3241 dump_spu_fields(spu_info[num].spu);
3244 dump_spu_ls(num, subcmd);
3256 static int do_spu_cmd(
void)