2 * Routines providing a simple monitor for use on the PowerMac.
4 * Copyright (C) 1996-2005 Paul Mackerras.
5 * Copyright (C) 2001 PPC64 Team, IBM Corp
6 * Copyrignt (C) 2006 Michael Ellerman, IBM Corp
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
13 #include <linux/errno.h>
14 #include <linux/sched.h>
15 #include <linux/smp.h>
17 #include <linux/reboot.h>
18 #include <linux/delay.h>
19 #include <linux/kallsyms.h>
20 #include <linux/kmsg_dump.h>
21 #include <linux/cpumask.h>
22 #include <linux/export.h>
23 #include <linux/sysrq.h>
24 #include <linux/interrupt.h>
25 #include <linux/irq.h>
26 #include <linux/bug.h>
27 #include <linux/nmi.h>
29 #include <asm/ptrace.h>
30 #include <asm/string.h>
32 #include <asm/machdep.h>
34 #include <asm/processor.h>
35 #include <asm/pgtable.h>
37 #include <asm/mmu_context.h>
38 #include <asm/cputable.h>
40 #include <asm/sstep.h>
41 #include <asm/irq_regs.h>
43 #include <asm/spu_priv1.h>
44 #include <asm/setjmp.h>
46 #include <asm/debug.h>
47 #include <asm/hw_breakpoint.h>
50 #include <asm/hvcall.h>
54 #if defined(CONFIG_PPC_SPLPAR)
55 #include <asm/plpar_wrappers.h>
57 static inline long plapr_set_ciabr(unsigned long ciabr
) {return 0; };
64 static cpumask_t cpus_in_xmon
= CPU_MASK_NONE
;
65 static unsigned long xmon_taken
= 1;
66 static int xmon_owner
;
70 #endif /* CONFIG_SMP */
72 static unsigned long in_xmon __read_mostly
= 0;
74 static unsigned long adrs
;
76 #define MAX_DUMP (128 * 1024)
77 static unsigned long ndump
= 64;
78 static unsigned long nidump
= 16;
79 static unsigned long ncsum
= 4096;
81 static char tmpstr
[128];
83 static long bus_error_jmp
[JMP_BUF_LEN
];
84 static int catch_memory_errors
;
85 static long *xmon_fault_jmp
[NR_CPUS
];
87 /* Breakpoint stuff */
89 unsigned long address
;
90 unsigned int instr
[2];
96 /* Bits in bpt.enabled */
102 static struct bpt bpts
[NBPTS
];
103 static struct bpt dabr
;
104 static struct bpt
*iabr
;
105 static unsigned bpinstr
= 0x7fe00008; /* trap */
107 #define BP_NUM(bp) ((bp) - bpts + 1)
110 static int cmds(struct pt_regs
*);
111 static int mread(unsigned long, void *, int);
112 static int mwrite(unsigned long, void *, int);
113 static int handle_fault(struct pt_regs
*);
114 static void byterev(unsigned char *, int);
115 static void memex(void);
116 static int bsesc(void);
117 static void dump(void);
118 static void prdump(unsigned long, long);
119 static int ppc_inst_dump(unsigned long, long, int);
120 static void dump_log_buf(void);
121 static void backtrace(struct pt_regs
*);
122 static void excprint(struct pt_regs
*);
123 static void prregs(struct pt_regs
*);
124 static void memops(int);
125 static void memlocate(void);
126 static void memzcan(void);
127 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
129 int scanhex(unsigned long *valp
);
130 static void scannl(void);
131 static int hexdigit(int);
132 void getstring(char *, int);
133 static void flush_input(void);
134 static int inchar(void);
135 static void take_input(char *);
136 static unsigned long read_spr(int);
137 static void write_spr(int, unsigned long);
138 static void super_regs(void);
139 static void remove_bpts(void);
140 static void insert_bpts(void);
141 static void remove_cpu_bpts(void);
142 static void insert_cpu_bpts(void);
143 static struct bpt
*at_breakpoint(unsigned long pc
);
144 static struct bpt
*in_breakpoint_table(unsigned long pc
, unsigned long *offp
);
145 static int do_step(struct pt_regs
*);
146 static void bpt_cmds(void);
147 static void cacheflush(void);
148 static int cpu_cmd(void);
149 static void csum(void);
150 static void bootcmds(void);
151 static void proccall(void);
152 void dump_segments(void);
153 static void symbol_lookup(void);
154 static void xmon_show_stack(unsigned long sp
, unsigned long lr
,
156 static void xmon_print_symbol(unsigned long address
, const char *mid
,
158 static const char *getvecname(unsigned long vec
);
160 static int do_spu_cmd(void);
163 static void dump_tlb_44x(void);
165 #ifdef CONFIG_PPC_BOOK3E
166 static void dump_tlb_book3e(void);
169 static int xmon_no_auto_backtrace
;
171 extern void xmon_enter(void);
172 extern void xmon_leave(void);
180 #ifdef __LITTLE_ENDIAN__
181 #define GETWORD(v) (((v)[3] << 24) + ((v)[2] << 16) + ((v)[1] << 8) + (v)[0])
183 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
186 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
187 || ('a' <= (c) && (c) <= 'f') \
188 || ('A' <= (c) && (c) <= 'F'))
189 #define isalnum(c) (('0' <= (c) && (c) <= '9') \
190 || ('a' <= (c) && (c) <= 'z') \
191 || ('A' <= (c) && (c) <= 'Z'))
192 #define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
194 static char *help_string
= "\
196 b show breakpoints\n\
197 bd set data breakpoint\n\
198 bi set instruction breakpoint\n\
199 bc clear breakpoint\n"
202 c print cpus stopped in xmon\n\
203 c# try to switch to cpu number h (in hex)\n"
208 di dump instructions\n\
209 df dump float values\n\
210 dd dump double values\n\
211 dl dump the kernel log buffer\n"
214 dp[#] dump paca for current cpu, or cpu #\n\
215 dpa dump paca for all possible cpus\n"
218 dr dump stream of raw bytes\n\
219 e print exception information\n\
221 la lookup symbol+offset of specified address\n\
222 ls lookup address of specified symbol\n\
223 m examine/change memory\n\
224 mm move a block of memory\n\
225 ms set a block of memory\n\
226 md compare two blocks of memory\n\
227 ml locate a block of memory\n\
228 mz zero a block of memory\n\
229 mi show information about memory allocation\n\
230 p call a procedure\n\
233 #ifdef CONFIG_SPU_BASE
234 " ss stop execution on all spus\n\
235 sr restore execution on stopped spus\n\
236 sf # dump spu fields for spu # (in hex)\n\
237 sd # dump spu local store for spu # (in hex)\n\
238 sdi # disassemble spu local store for spu # (in hex)\n"
240 " S print special registers\n\
242 x exit monitor and recover\n\
243 X exit monitor and dont recover\n"
244 #if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_BOOK3E)
245 " u dump segment table or SLB\n"
246 #elif defined(CONFIG_PPC_STD_MMU_32)
247 " u dump segment registers\n"
248 #elif defined(CONFIG_44x) || defined(CONFIG_PPC_BOOK3E)
256 static struct pt_regs
*xmon_regs
;
258 static inline void sync(void)
260 asm volatile("sync; isync");
263 static inline void store_inst(void *p
)
265 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p
));
268 static inline void cflush(void *p
)
270 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p
));
273 static inline void cinval(void *p
)
275 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p
));
279 * write_ciabr() - write the CIABR SPR
280 * @ciabr: The value to write.
282 * This function writes a value to the CIARB register either directly
283 * through mtspr instruction if the kernel is in HV privilege mode or
284 * call a hypervisor function to achieve the same in case the kernel
285 * is in supervisor privilege mode.
287 static void write_ciabr(unsigned long ciabr
)
289 if (!cpu_has_feature(CPU_FTR_ARCH_207S
))
292 if (cpu_has_feature(CPU_FTR_HVMODE
)) {
293 mtspr(SPRN_CIABR
, ciabr
);
296 plapr_set_ciabr(ciabr
);
300 * set_ciabr() - set the CIABR
301 * @addr: The value to set.
303 * This function sets the correct privilege value into the the HW
304 * breakpoint address before writing it up in the CIABR register.
306 static void set_ciabr(unsigned long addr
)
310 if (cpu_has_feature(CPU_FTR_HVMODE
))
311 addr
|= CIABR_PRIV_HYPER
;
313 addr
|= CIABR_PRIV_SUPER
;
318 * Disable surveillance (the service processor watchdog function)
319 * while we are in xmon.
320 * XXX we should re-enable it when we leave. :)
322 #define SURVEILLANCE_TOKEN 9000
324 static inline void disable_surveillance(void)
326 #ifdef CONFIG_PPC_PSERIES
327 /* Since this can't be a module, args should end up below 4GB. */
328 static struct rtas_args args
;
331 * At this point we have got all the cpus we can into
332 * xmon, so there is hopefully no other cpu calling RTAS
333 * at the moment, even though we don't take rtas.lock.
334 * If we did try to take rtas.lock there would be a
335 * real possibility of deadlock.
337 args
.token
= rtas_token("set-indicator");
338 if (args
.token
== RTAS_UNKNOWN_SERVICE
)
340 args
.token
= cpu_to_be32(args
.token
);
341 args
.nargs
= cpu_to_be32(3);
342 args
.nret
= cpu_to_be32(1);
343 args
.rets
= &args
.args
[3];
344 args
.args
[0] = cpu_to_be32(SURVEILLANCE_TOKEN
);
347 enter_rtas(__pa(&args
));
348 #endif /* CONFIG_PPC_PSERIES */
352 static int xmon_speaker
;
354 static void get_output_lock(void)
356 int me
= smp_processor_id() + 0x100;
357 int last_speaker
= 0, prev
;
360 if (xmon_speaker
== me
)
364 last_speaker
= cmpxchg(&xmon_speaker
, 0, me
);
365 if (last_speaker
== 0)
369 * Wait a full second for the lock, we might be on a slow
370 * console, but check every 100us.
373 while (xmon_speaker
== last_speaker
) {
379 /* hostile takeover */
380 prev
= cmpxchg(&xmon_speaker
, last_speaker
, me
);
381 if (prev
== last_speaker
)
388 static void release_output_lock(void)
393 int cpus_are_in_xmon(void)
395 return !cpumask_empty(&cpus_in_xmon
);
399 static inline int unrecoverable_excp(struct pt_regs
*regs
)
401 #if defined(CONFIG_4xx) || defined(CONFIG_PPC_BOOK3E)
402 /* We have no MSR_RI bit on 4xx or Book3e, so we simply return false */
405 return ((regs
->msr
& MSR_RI
) == 0);
409 static int xmon_core(struct pt_regs
*regs
, int fromipi
)
413 long recurse_jmp
[JMP_BUF_LEN
];
414 unsigned long offset
;
419 unsigned long timeout
;
422 local_irq_save(flags
);
425 bp
= in_breakpoint_table(regs
->nip
, &offset
);
427 regs
->nip
= bp
->address
+ offset
;
428 atomic_dec(&bp
->ref_count
);
434 cpu
= smp_processor_id();
435 if (cpumask_test_cpu(cpu
, &cpus_in_xmon
)) {
438 printf("cpu 0x%x: Exception %lx %s in xmon, "
439 "returning to main loop\n",
440 cpu
, regs
->trap
, getvecname(TRAP(regs
)));
441 release_output_lock();
442 longjmp(xmon_fault_jmp
[cpu
], 1);
445 if (setjmp(recurse_jmp
) != 0) {
446 if (!in_xmon
|| !xmon_gate
) {
448 printf("xmon: WARNING: bad recursive fault "
449 "on cpu 0x%x\n", cpu
);
450 release_output_lock();
453 secondary
= !(xmon_taken
&& cpu
== xmon_owner
);
457 xmon_fault_jmp
[cpu
] = recurse_jmp
;
460 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) == (MSR_IR
|MSR_64BIT
))
461 bp
= at_breakpoint(regs
->nip
);
462 if (bp
|| unrecoverable_excp(regs
))
469 printf("cpu 0x%x stopped at breakpoint 0x%lx (",
471 xmon_print_symbol(regs
->nip
, " ", ")\n");
473 if (unrecoverable_excp(regs
))
474 printf("WARNING: exception is not recoverable, "
476 release_output_lock();
479 cpumask_set_cpu(cpu
, &cpus_in_xmon
);
483 while (secondary
&& !xmon_gate
) {
487 secondary
= test_and_set_bit(0, &in_xmon
);
492 if (!secondary
&& !xmon_gate
) {
493 /* we are the first cpu to come in */
494 /* interrupt other cpu(s) */
495 int ncpus
= num_online_cpus();
500 smp_send_debugger_break();
501 /* wait for other cpus to come in */
502 for (timeout
= 100000000; timeout
!= 0; --timeout
) {
503 if (cpumask_weight(&cpus_in_xmon
) >= ncpus
)
509 disable_surveillance();
510 /* for breakpoint or single step, print the current instr. */
511 if (bp
|| TRAP(regs
) == 0xd00)
512 ppc_inst_dump(regs
->nip
, 1, 0);
513 printf("enter ? for help\n");
522 if (cpu
== xmon_owner
) {
523 if (!test_and_set_bit(0, &xmon_taken
)) {
528 while (cpu
== xmon_owner
)
542 /* have switched to some other cpu */
547 cpumask_clear_cpu(cpu
, &cpus_in_xmon
);
548 xmon_fault_jmp
[cpu
] = NULL
;
550 /* UP is simple... */
552 printf("Exception %lx %s in xmon, returning to main loop\n",
553 regs
->trap
, getvecname(TRAP(regs
)));
554 longjmp(xmon_fault_jmp
[0], 1);
556 if (setjmp(recurse_jmp
) == 0) {
557 xmon_fault_jmp
[0] = recurse_jmp
;
561 bp
= at_breakpoint(regs
->nip
);
563 printf("Stopped at breakpoint %lx (", BP_NUM(bp
));
564 xmon_print_symbol(regs
->nip
, " ", ")\n");
566 if (unrecoverable_excp(regs
))
567 printf("WARNING: exception is not recoverable, "
570 disable_surveillance();
571 /* for breakpoint or single step, print the current instr. */
572 if (bp
|| TRAP(regs
) == 0xd00)
573 ppc_inst_dump(regs
->nip
, 1, 0);
574 printf("enter ? for help\n");
584 if (regs
->msr
& MSR_DE
) {
585 bp
= at_breakpoint(regs
->nip
);
587 regs
->nip
= (unsigned long) &bp
->instr
[0];
588 atomic_inc(&bp
->ref_count
);
592 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) == (MSR_IR
|MSR_64BIT
)) {
593 bp
= at_breakpoint(regs
->nip
);
595 int stepped
= emulate_step(regs
, bp
->instr
[0]);
597 regs
->nip
= (unsigned long) &bp
->instr
[0];
598 atomic_inc(&bp
->ref_count
);
599 } else if (stepped
< 0) {
600 printf("Couldn't single-step %s instruction\n",
601 (IS_RFID(bp
->instr
[0])? "rfid": "mtmsrd"));
608 touch_nmi_watchdog();
609 local_irq_restore(flags
);
611 return cmd
!= 'X' && cmd
!= EOF
;
614 int xmon(struct pt_regs
*excp
)
619 ppc_save_regs(®s
);
623 return xmon_core(excp
, 0);
627 irqreturn_t
xmon_irq(int irq
, void *d
)
630 local_irq_save(flags
);
631 printf("Keyboard interrupt\n");
632 xmon(get_irq_regs());
633 local_irq_restore(flags
);
637 static int xmon_bpt(struct pt_regs
*regs
)
640 unsigned long offset
;
642 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) != (MSR_IR
|MSR_64BIT
))
645 /* Are we at the trap at bp->instr[1] for some bp? */
646 bp
= in_breakpoint_table(regs
->nip
, &offset
);
647 if (bp
!= NULL
&& offset
== 4) {
648 regs
->nip
= bp
->address
+ 4;
649 atomic_dec(&bp
->ref_count
);
653 /* Are we at a breakpoint? */
654 bp
= at_breakpoint(regs
->nip
);
663 static int xmon_sstep(struct pt_regs
*regs
)
671 static int xmon_break_match(struct pt_regs
*regs
)
673 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) != (MSR_IR
|MSR_64BIT
))
675 if (dabr
.enabled
== 0)
681 static int xmon_iabr_match(struct pt_regs
*regs
)
683 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) != (MSR_IR
|MSR_64BIT
))
691 static int xmon_ipi(struct pt_regs
*regs
)
694 if (in_xmon
&& !cpumask_test_cpu(smp_processor_id(), &cpus_in_xmon
))
700 static int xmon_fault_handler(struct pt_regs
*regs
)
703 unsigned long offset
;
705 if (in_xmon
&& catch_memory_errors
)
706 handle_fault(regs
); /* doesn't return */
708 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_64BIT
)) == (MSR_IR
|MSR_64BIT
)) {
709 bp
= in_breakpoint_table(regs
->nip
, &offset
);
711 regs
->nip
= bp
->address
+ offset
;
712 atomic_dec(&bp
->ref_count
);
719 static struct bpt
*at_breakpoint(unsigned long pc
)
725 for (i
= 0; i
< NBPTS
; ++i
, ++bp
)
726 if (bp
->enabled
&& pc
== bp
->address
)
731 static struct bpt
*in_breakpoint_table(unsigned long nip
, unsigned long *offp
)
735 off
= nip
- (unsigned long) bpts
;
736 if (off
>= sizeof(bpts
))
738 off
%= sizeof(struct bpt
);
739 if (off
!= offsetof(struct bpt
, instr
[0])
740 && off
!= offsetof(struct bpt
, instr
[1]))
742 *offp
= off
- offsetof(struct bpt
, instr
[0]);
743 return (struct bpt
*) (nip
- off
);
746 static struct bpt
*new_breakpoint(unsigned long a
)
751 bp
= at_breakpoint(a
);
755 for (bp
= bpts
; bp
< &bpts
[NBPTS
]; ++bp
) {
756 if (!bp
->enabled
&& atomic_read(&bp
->ref_count
) == 0) {
758 bp
->instr
[1] = bpinstr
;
759 store_inst(&bp
->instr
[1]);
764 printf("Sorry, no free breakpoints. Please clear one first.\n");
768 static void insert_bpts(void)
774 for (i
= 0; i
< NBPTS
; ++i
, ++bp
) {
775 if ((bp
->enabled
& (BP_TRAP
|BP_CIABR
)) == 0)
777 if (mread(bp
->address
, &bp
->instr
[0], 4) != 4) {
778 printf("Couldn't read instruction at %lx, "
779 "disabling breakpoint there\n", bp
->address
);
783 if (IS_MTMSRD(bp
->instr
[0]) || IS_RFID(bp
->instr
[0])) {
784 printf("Breakpoint at %lx is on an mtmsrd or rfid "
785 "instruction, disabling it\n", bp
->address
);
789 store_inst(&bp
->instr
[0]);
790 if (bp
->enabled
& BP_CIABR
)
792 if (mwrite(bp
->address
, &bpinstr
, 4) != 4) {
793 printf("Couldn't write instruction at %lx, "
794 "disabling breakpoint there\n", bp
->address
);
795 bp
->enabled
&= ~BP_TRAP
;
798 store_inst((void *)bp
->address
);
802 static void insert_cpu_bpts(void)
804 struct arch_hw_breakpoint brk
;
807 brk
.address
= dabr
.address
;
808 brk
.type
= (dabr
.enabled
& HW_BRK_TYPE_DABR
) | HW_BRK_TYPE_PRIV_ALL
;
810 __set_breakpoint(&brk
);
814 set_ciabr(iabr
->address
);
817 static void remove_bpts(void)
824 for (i
= 0; i
< NBPTS
; ++i
, ++bp
) {
825 if ((bp
->enabled
& (BP_TRAP
|BP_CIABR
)) != BP_TRAP
)
827 if (mread(bp
->address
, &instr
, 4) == 4
829 && mwrite(bp
->address
, &bp
->instr
, 4) != 4)
830 printf("Couldn't remove breakpoint at %lx\n",
833 store_inst((void *)bp
->address
);
837 static void remove_cpu_bpts(void)
839 hw_breakpoint_disable();
843 /* Command interpreting routine */
844 static char *last_cmd
;
847 cmds(struct pt_regs
*excp
)
854 if (!xmon_no_auto_backtrace
) {
855 xmon_no_auto_backtrace
= 1;
856 xmon_show_stack(excp
->gpr
[1], excp
->link
, excp
->nip
);
861 printf("%x:", smp_processor_id());
862 #endif /* CONFIG_SMP */
868 if (last_cmd
== NULL
)
870 take_input(last_cmd
);
904 prregs(excp
); /* print regs */
919 if (do_spu_cmd() == 0)
928 printf(" <no input ...>\n");
932 xmon_puts(help_string
);
950 #ifdef CONFIG_PPC_STD_MMU
954 #elif defined(CONFIG_44x)
958 #elif defined(CONFIG_PPC_BOOK3E)
964 printf("Unrecognized command: ");
966 if (' ' < cmd
&& cmd
<= '~')
969 printf("\\x%x", cmd
);
971 } while (cmd
!= '\n');
972 printf(" (type ? for help)\n");
979 static int do_step(struct pt_regs
*regs
)
982 mtspr(SPRN_DBCR0
, mfspr(SPRN_DBCR0
) | DBCR0_IC
| DBCR0_IDM
);
987 * Step a single instruction.
988 * Some instructions we emulate, others we execute with MSR_SE set.
990 static int do_step(struct pt_regs
*regs
)
995 /* check we are in 64-bit kernel mode, translation enabled */
996 if ((regs
->msr
& (MSR_64BIT
|MSR_PR
|MSR_IR
)) == (MSR_64BIT
|MSR_IR
)) {
997 if (mread(regs
->nip
, &instr
, 4) == 4) {
998 stepped
= emulate_step(regs
, instr
);
1000 printf("Couldn't single-step %s instruction\n",
1001 (IS_RFID(instr
)? "rfid": "mtmsrd"));
1005 regs
->trap
= 0xd00 | (regs
->trap
& 1);
1006 printf("stepped to ");
1007 xmon_print_symbol(regs
->nip
, " ", "\n");
1008 ppc_inst_dump(regs
->nip
, 1, 0);
1013 regs
->msr
|= MSR_SE
;
1018 static void bootcmds(void)
1024 ppc_md
.restart(NULL
);
1025 else if (cmd
== 'h')
1027 else if (cmd
== 'p')
1032 static int cpu_cmd(void)
1035 unsigned long cpu
, first_cpu
, last_cpu
;
1038 if (!scanhex(&cpu
)) {
1039 /* print cpus waiting or in xmon */
1040 printf("cpus stopped:");
1041 last_cpu
= first_cpu
= NR_CPUS
;
1042 for_each_possible_cpu(cpu
) {
1043 if (cpumask_test_cpu(cpu
, &cpus_in_xmon
)) {
1044 if (cpu
== last_cpu
+ 1) {
1047 if (last_cpu
!= first_cpu
)
1048 printf("-0x%lx", last_cpu
);
1049 last_cpu
= first_cpu
= cpu
;
1050 printf(" 0x%lx", cpu
);
1054 if (last_cpu
!= first_cpu
)
1055 printf("-0x%lx", last_cpu
);
1059 /* try to switch to cpu specified */
1060 if (!cpumask_test_cpu(cpu
, &cpus_in_xmon
)) {
1061 printf("cpu 0x%x isn't in xmon\n", cpu
);
1068 while (!xmon_taken
) {
1069 if (--timeout
== 0) {
1070 if (test_and_set_bit(0, &xmon_taken
))
1072 /* take control back */
1074 xmon_owner
= smp_processor_id();
1075 printf("cpu 0x%x didn't take control\n", cpu
);
1083 #endif /* CONFIG_SMP */
1086 static unsigned short fcstab
[256] = {
1087 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
1088 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
1089 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
1090 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1091 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1092 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1093 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1094 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1095 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1096 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1097 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1098 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1099 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1100 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1101 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1102 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1103 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1104 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1105 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1106 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1107 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1108 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1109 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1110 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1111 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1112 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1113 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1114 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1115 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1116 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1117 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1118 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1121 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1130 if (!scanhex(&adrs
))
1132 if (!scanhex(&ncsum
))
1135 for (i
= 0; i
< ncsum
; ++i
) {
1136 if (mread(adrs
+i
, &v
, 1) == 0) {
1137 printf("csum stopped at "REG
"\n", adrs
+i
);
1142 printf("%x\n", fcs
);
1146 * Check if this is a suitable place to put a breakpoint.
1148 static long check_bp_loc(unsigned long addr
)
1153 if (!is_kernel_addr(addr
)) {
1154 printf("Breakpoints may only be placed at kernel addresses\n");
1157 if (!mread(addr
, &instr
, sizeof(instr
))) {
1158 printf("Can't read instruction at address %lx\n", addr
);
1161 if (IS_MTMSRD(instr
) || IS_RFID(instr
)) {
1162 printf("Breakpoints may not be placed on mtmsrd or rfid "
1169 static char *breakpoint_help_string
=
1170 "Breakpoint command usage:\n"
1171 "b show breakpoints\n"
1172 "b <addr> [cnt] set breakpoint at given instr addr\n"
1173 "bc clear all breakpoints\n"
1174 "bc <n/addr> clear breakpoint number n or at addr\n"
1175 "bi <addr> [cnt] set hardware instr breakpoint (POWER8 only)\n"
1176 "bd <addr> [cnt] set hardware data breakpoint\n"
1186 const char badaddr
[] = "Only kernel addresses are permitted "
1187 "for breakpoints\n";
1192 case 'd': /* bd - hardware data breakpoint */
1197 else if (cmd
== 'w')
1203 if (scanhex(&dabr
.address
)) {
1204 if (!is_kernel_addr(dabr
.address
)) {
1208 dabr
.address
&= ~HW_BRK_TYPE_DABR
;
1209 dabr
.enabled
= mode
| BP_DABR
;
1213 case 'i': /* bi - hardware instr breakpoint */
1214 if (!cpu_has_feature(CPU_FTR_ARCH_207S
)) {
1215 printf("Hardware instruction breakpoint "
1216 "not supported on this cpu\n");
1220 iabr
->enabled
&= ~BP_CIABR
;
1225 if (!check_bp_loc(a
))
1227 bp
= new_breakpoint(a
);
1229 bp
->enabled
|= BP_CIABR
;
1237 /* clear all breakpoints */
1238 for (i
= 0; i
< NBPTS
; ++i
)
1239 bpts
[i
].enabled
= 0;
1242 printf("All breakpoints cleared\n");
1246 if (a
<= NBPTS
&& a
>= 1) {
1247 /* assume a breakpoint number */
1248 bp
= &bpts
[a
-1]; /* bp nums are 1 based */
1250 /* assume a breakpoint address */
1251 bp
= at_breakpoint(a
);
1253 printf("No breakpoint at %lx\n", a
);
1258 printf("Cleared breakpoint %lx (", BP_NUM(bp
));
1259 xmon_print_symbol(bp
->address
, " ", ")\n");
1267 printf(breakpoint_help_string
);
1272 /* print all breakpoints */
1273 printf(" type address\n");
1275 printf(" data "REG
" [", dabr
.address
);
1276 if (dabr
.enabled
& 1)
1278 if (dabr
.enabled
& 2)
1282 for (bp
= bpts
; bp
< &bpts
[NBPTS
]; ++bp
) {
1285 printf("%2x %s ", BP_NUM(bp
),
1286 (bp
->enabled
& BP_CIABR
) ? "inst": "trap");
1287 xmon_print_symbol(bp
->address
, " ", "\n");
1292 if (!check_bp_loc(a
))
1294 bp
= new_breakpoint(a
);
1296 bp
->enabled
|= BP_TRAP
;
1301 /* Very cheap human name for vector lookup. */
1303 const char *getvecname(unsigned long vec
)
1308 case 0x100: ret
= "(System Reset)"; break;
1309 case 0x200: ret
= "(Machine Check)"; break;
1310 case 0x300: ret
= "(Data Access)"; break;
1311 case 0x380: ret
= "(Data SLB Access)"; break;
1312 case 0x400: ret
= "(Instruction Access)"; break;
1313 case 0x480: ret
= "(Instruction SLB Access)"; break;
1314 case 0x500: ret
= "(Hardware Interrupt)"; break;
1315 case 0x600: ret
= "(Alignment)"; break;
1316 case 0x700: ret
= "(Program Check)"; break;
1317 case 0x800: ret
= "(FPU Unavailable)"; break;
1318 case 0x900: ret
= "(Decrementer)"; break;
1319 case 0x980: ret
= "(Hypervisor Decrementer)"; break;
1320 case 0xa00: ret
= "(Doorbell)"; break;
1321 case 0xc00: ret
= "(System Call)"; break;
1322 case 0xd00: ret
= "(Single Step)"; break;
1323 case 0xe40: ret
= "(Emulation Assist)"; break;
1324 case 0xe60: ret
= "(HMI)"; break;
1325 case 0xe80: ret
= "(Hypervisor Doorbell)"; break;
1326 case 0xf00: ret
= "(Performance Monitor)"; break;
1327 case 0xf20: ret
= "(Altivec Unavailable)"; break;
1328 case 0x1300: ret
= "(Instruction Breakpoint)"; break;
1329 case 0x1500: ret
= "(Denormalisation)"; break;
1330 case 0x1700: ret
= "(Altivec Assist)"; break;
1336 static void get_function_bounds(unsigned long pc
, unsigned long *startp
,
1337 unsigned long *endp
)
1339 unsigned long size
, offset
;
1342 *startp
= *endp
= 0;
1345 if (setjmp(bus_error_jmp
) == 0) {
1346 catch_memory_errors
= 1;
1348 name
= kallsyms_lookup(pc
, &size
, &offset
, NULL
, tmpstr
);
1350 *startp
= pc
- offset
;
1351 *endp
= pc
- offset
+ size
;
1355 catch_memory_errors
= 0;
1358 #define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1359 #define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long))
1361 static void xmon_show_stack(unsigned long sp
, unsigned long lr
,
1364 int max_to_print
= 64;
1366 unsigned long newsp
;
1367 unsigned long marker
;
1368 struct pt_regs regs
;
1370 while (max_to_print
--) {
1371 if (sp
< PAGE_OFFSET
) {
1373 printf("SP (%lx) is in userspace\n", sp
);
1377 if (!mread(sp
+ LRSAVE_OFFSET
, &ip
, sizeof(unsigned long))
1378 || !mread(sp
, &newsp
, sizeof(unsigned long))) {
1379 printf("Couldn't read stack frame at %lx\n", sp
);
1384 * For the first stack frame, try to work out if
1385 * LR and/or the saved LR value in the bottommost
1386 * stack frame are valid.
1388 if ((pc
| lr
) != 0) {
1389 unsigned long fnstart
, fnend
;
1390 unsigned long nextip
;
1393 get_function_bounds(pc
, &fnstart
, &fnend
);
1396 mread(newsp
+ LRSAVE_OFFSET
, &nextip
,
1397 sizeof(unsigned long));
1399 if (lr
< PAGE_OFFSET
1400 || (fnstart
<= lr
&& lr
< fnend
))
1402 } else if (lr
== nextip
) {
1404 } else if (lr
>= PAGE_OFFSET
1405 && !(fnstart
<= lr
&& lr
< fnend
)) {
1406 printf("[link register ] ");
1407 xmon_print_symbol(lr
, " ", "\n");
1410 printf("["REG
"] ", sp
);
1411 xmon_print_symbol(ip
, " ", " (unreliable)\n");
1416 printf("["REG
"] ", sp
);
1417 xmon_print_symbol(ip
, " ", "\n");
1420 /* Look for "regshere" marker to see if this is
1421 an exception frame. */
1422 if (mread(sp
+ MARKER_OFFSET
, &marker
, sizeof(unsigned long))
1423 && marker
== STACK_FRAME_REGS_MARKER
) {
1424 if (mread(sp
+ STACK_FRAME_OVERHEAD
, ®s
, sizeof(regs
))
1426 printf("Couldn't read registers at %lx\n",
1427 sp
+ STACK_FRAME_OVERHEAD
);
1430 printf("--- Exception: %lx %s at ", regs
.trap
,
1431 getvecname(TRAP(®s
)));
1434 xmon_print_symbol(pc
, " ", "\n");
1444 static void backtrace(struct pt_regs
*excp
)
1449 xmon_show_stack(sp
, 0, 0);
1451 xmon_show_stack(excp
->gpr
[1], excp
->link
, excp
->nip
);
1455 static void print_bug_trap(struct pt_regs
*regs
)
1458 const struct bug_entry
*bug
;
1461 if (regs
->msr
& MSR_PR
)
1462 return; /* not in kernel */
1463 addr
= regs
->nip
; /* address of trap instruction */
1464 if (addr
< PAGE_OFFSET
)
1466 bug
= find_bug(regs
->nip
);
1469 if (is_warning_bug(bug
))
1472 #ifdef CONFIG_DEBUG_BUGVERBOSE
1473 printf("kernel BUG at %s:%u!\n",
1474 bug
->file
, bug
->line
);
1476 printf("kernel BUG at %p!\n", (void *)bug
->bug_addr
);
1478 #endif /* CONFIG_BUG */
1481 static void excprint(struct pt_regs
*fp
)
1486 printf("cpu 0x%x: ", smp_processor_id());
1487 #endif /* CONFIG_SMP */
1490 printf("Vector: %lx %s at [%lx]\n", fp
->trap
, getvecname(trap
), fp
);
1492 xmon_print_symbol(fp
->nip
, ": ", "\n");
1494 printf(" lr: ", fp
->link
);
1495 xmon_print_symbol(fp
->link
, ": ", "\n");
1497 printf(" sp: %lx\n", fp
->gpr
[1]);
1498 printf(" msr: %lx\n", fp
->msr
);
1500 if (trap
== 0x300 || trap
== 0x380 || trap
== 0x600 || trap
== 0x200) {
1501 printf(" dar: %lx\n", fp
->dar
);
1503 printf(" dsisr: %lx\n", fp
->dsisr
);
1506 printf(" current = 0x%lx\n", current
);
1508 printf(" paca = 0x%lx\t softe: %d\t irq_happened: 0x%02x\n",
1509 local_paca
, local_paca
->soft_enabled
, local_paca
->irq_happened
);
1512 printf(" pid = %ld, comm = %s\n",
1513 current
->pid
, current
->comm
);
1520 static void prregs(struct pt_regs
*fp
)
1524 struct pt_regs regs
;
1526 if (scanhex(&base
)) {
1527 if (setjmp(bus_error_jmp
) == 0) {
1528 catch_memory_errors
= 1;
1530 regs
= *(struct pt_regs
*)base
;
1534 catch_memory_errors
= 0;
1535 printf("*** Error reading registers from "REG
"\n",
1539 catch_memory_errors
= 0;
1544 if (FULL_REGS(fp
)) {
1545 for (n
= 0; n
< 16; ++n
)
1546 printf("R%.2ld = "REG
" R%.2ld = "REG
"\n",
1547 n
, fp
->gpr
[n
], n
+16, fp
->gpr
[n
+16]);
1549 for (n
= 0; n
< 7; ++n
)
1550 printf("R%.2ld = "REG
" R%.2ld = "REG
"\n",
1551 n
, fp
->gpr
[n
], n
+7, fp
->gpr
[n
+7]);
1554 for (n
= 0; n
< 32; ++n
) {
1555 printf("R%.2d = %.8x%s", n
, fp
->gpr
[n
],
1556 (n
& 3) == 3? "\n": " ");
1557 if (n
== 12 && !FULL_REGS(fp
)) {
1564 xmon_print_symbol(fp
->nip
, " ", "\n");
1565 if (TRAP(fp
) != 0xc00 && cpu_has_feature(CPU_FTR_CFAR
)) {
1567 xmon_print_symbol(fp
->orig_gpr3
, " ", "\n");
1570 xmon_print_symbol(fp
->link
, " ", "\n");
1571 printf("msr = "REG
" cr = %.8lx\n", fp
->msr
, fp
->ccr
);
1572 printf("ctr = "REG
" xer = "REG
" trap = %4lx\n",
1573 fp
->ctr
, fp
->xer
, fp
->trap
);
1575 if (trap
== 0x300 || trap
== 0x380 || trap
== 0x600)
1576 printf("dar = "REG
" dsisr = %.8lx\n", fp
->dar
, fp
->dsisr
);
1579 static void cacheflush(void)
1582 unsigned long nflush
;
1587 scanhex((void *)&adrs
);
1592 nflush
= (nflush
+ L1_CACHE_BYTES
- 1) / L1_CACHE_BYTES
;
1593 if (setjmp(bus_error_jmp
) == 0) {
1594 catch_memory_errors
= 1;
1598 for (; nflush
> 0; --nflush
, adrs
+= L1_CACHE_BYTES
)
1599 cflush((void *) adrs
);
1601 for (; nflush
> 0; --nflush
, adrs
+= L1_CACHE_BYTES
)
1602 cinval((void *) adrs
);
1605 /* wait a little while to see if we get a machine check */
1608 catch_memory_errors
= 0;
1611 static unsigned long
1614 unsigned int instrs
[2];
1615 unsigned long (*code
)(void);
1616 unsigned long ret
= -1UL;
1618 unsigned long opd
[3];
1620 opd
[0] = (unsigned long)instrs
;
1623 code
= (unsigned long (*)(void)) opd
;
1625 code
= (unsigned long (*)(void)) instrs
;
1628 /* mfspr r3,n; blr */
1629 instrs
[0] = 0x7c6002a6 + ((n
& 0x1F) << 16) + ((n
& 0x3e0) << 6);
1630 instrs
[1] = 0x4e800020;
1632 store_inst(instrs
+1);
1634 if (setjmp(bus_error_jmp
) == 0) {
1635 catch_memory_errors
= 1;
1641 /* wait a little while to see if we get a machine check */
1650 write_spr(int n
, unsigned long val
)
1652 unsigned int instrs
[2];
1653 unsigned long (*code
)(unsigned long);
1655 unsigned long opd
[3];
1657 opd
[0] = (unsigned long)instrs
;
1660 code
= (unsigned long (*)(unsigned long)) opd
;
1662 code
= (unsigned long (*)(unsigned long)) instrs
;
1665 instrs
[0] = 0x7c6003a6 + ((n
& 0x1F) << 16) + ((n
& 0x3e0) << 6);
1666 instrs
[1] = 0x4e800020;
1668 store_inst(instrs
+1);
1670 if (setjmp(bus_error_jmp
) == 0) {
1671 catch_memory_errors
= 1;
1677 /* wait a little while to see if we get a machine check */
1683 static unsigned long regno
;
1684 extern char exc_prolog
;
1685 extern char dec_exc
;
1687 static void super_regs(void)
1694 unsigned long sp
, toc
;
1695 asm("mr %0,1" : "=r" (sp
) :);
1696 asm("mr %0,2" : "=r" (toc
) :);
1698 printf("msr = "REG
" sprg0= "REG
"\n",
1699 mfmsr(), mfspr(SPRN_SPRG0
));
1700 printf("pvr = "REG
" sprg1= "REG
"\n",
1701 mfspr(SPRN_PVR
), mfspr(SPRN_SPRG1
));
1702 printf("dec = "REG
" sprg2= "REG
"\n",
1703 mfspr(SPRN_DEC
), mfspr(SPRN_SPRG2
));
1704 printf("sp = "REG
" sprg3= "REG
"\n", sp
, mfspr(SPRN_SPRG3
));
1705 printf("toc = "REG
" dar = "REG
"\n", toc
, mfspr(SPRN_DAR
));
1713 val
= read_spr(regno
);
1715 write_spr(regno
, val
);
1718 printf("spr %lx = %lx\n", regno
, read_spr(regno
));
1725 * Stuff for reading and writing memory safely
1728 mread(unsigned long adrs
, void *buf
, int size
)
1734 if (setjmp(bus_error_jmp
) == 0) {
1735 catch_memory_errors
= 1;
1741 *(u16
*)q
= *(u16
*)p
;
1744 *(u32
*)q
= *(u32
*)p
;
1747 *(u64
*)q
= *(u64
*)p
;
1750 for( ; n
< size
; ++n
) {
1756 /* wait a little while to see if we get a machine check */
1760 catch_memory_errors
= 0;
1765 mwrite(unsigned long adrs
, void *buf
, int size
)
1771 if (setjmp(bus_error_jmp
) == 0) {
1772 catch_memory_errors
= 1;
1778 *(u16
*)p
= *(u16
*)q
;
1781 *(u32
*)p
= *(u32
*)q
;
1784 *(u64
*)p
= *(u64
*)q
;
1787 for ( ; n
< size
; ++n
) {
1793 /* wait a little while to see if we get a machine check */
1797 printf("*** Error writing address "REG
"\n", adrs
+ n
);
1799 catch_memory_errors
= 0;
1803 static int fault_type
;
1804 static int fault_except
;
1805 static char *fault_chars
[] = { "--", "**", "##" };
1807 static int handle_fault(struct pt_regs
*regs
)
1809 fault_except
= TRAP(regs
);
1810 switch (TRAP(regs
)) {
1822 longjmp(bus_error_jmp
, 1);
1827 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1830 byterev(unsigned char *val
, int size
)
1836 SWAP(val
[0], val
[1], t
);
1839 SWAP(val
[0], val
[3], t
);
1840 SWAP(val
[1], val
[2], t
);
1842 case 8: /* is there really any use for this? */
1843 SWAP(val
[0], val
[7], t
);
1844 SWAP(val
[1], val
[6], t
);
1845 SWAP(val
[2], val
[5], t
);
1846 SWAP(val
[3], val
[4], t
);
1854 static char *memex_help_string
=
1855 "Memory examine command usage:\n"
1856 "m [addr] [flags] examine/change memory\n"
1857 " addr is optional. will start where left off.\n"
1858 " flags may include chars from this set:\n"
1859 " b modify by bytes (default)\n"
1860 " w modify by words (2 byte)\n"
1861 " l modify by longs (4 byte)\n"
1862 " d modify by doubleword (8 byte)\n"
1863 " r toggle reverse byte order mode\n"
1864 " n do not read memory (for i/o spaces)\n"
1865 " . ok to read (default)\n"
1866 "NOTE: flags are saved as defaults\n"
1869 static char *memex_subcmd_help_string
=
1870 "Memory examine subcommands:\n"
1871 " hexval write this val to current location\n"
1872 " 'string' write chars from string to this location\n"
1873 " ' increment address\n"
1874 " ^ decrement address\n"
1875 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1876 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1877 " ` clear no-read flag\n"
1878 " ; stay at this addr\n"
1879 " v change to byte mode\n"
1880 " w change to word (2 byte) mode\n"
1881 " l change to long (4 byte) mode\n"
1882 " u change to doubleword (8 byte) mode\n"
1883 " m addr change current addr\n"
1884 " n toggle no-read flag\n"
1885 " r toggle byte reverse flag\n"
1886 " < count back up count bytes\n"
1887 " > count skip forward count bytes\n"
1888 " x exit this mode\n"
1894 int cmd
, inc
, i
, nslash
;
1896 unsigned char val
[16];
1898 scanhex((void *)&adrs
);
1901 printf(memex_help_string
);
1907 while ((cmd
= skipbl()) != '\n') {
1909 case 'b': size
= 1; break;
1910 case 'w': size
= 2; break;
1911 case 'l': size
= 4; break;
1912 case 'd': size
= 8; break;
1913 case 'r': brev
= !brev
; break;
1914 case 'n': mnoread
= 1; break;
1915 case '.': mnoread
= 0; break;
1924 n
= mread(adrs
, val
, size
);
1925 printf(REG
"%c", adrs
, brev
? 'r': ' ');
1930 for (i
= 0; i
< n
; ++i
)
1931 printf("%.2x", val
[i
]);
1932 for (; i
< size
; ++i
)
1933 printf("%s", fault_chars
[fault_type
]);
1940 for (i
= 0; i
< size
; ++i
)
1941 val
[i
] = n
>> (i
* 8);
1944 mwrite(adrs
, val
, size
);
1957 else if( n
== '\'' )
1959 for (i
= 0; i
< size
; ++i
)
1960 val
[i
] = n
>> (i
* 8);
1963 mwrite(adrs
, val
, size
);
2000 adrs
-= 1 << nslash
;
2004 adrs
+= 1 << nslash
;
2008 adrs
+= 1 << -nslash
;
2012 adrs
-= 1 << -nslash
;
2015 scanhex((void *)&adrs
);
2034 printf(memex_subcmd_help_string
);
2049 case 'n': c
= '\n'; break;
2050 case 'r': c
= '\r'; break;
2051 case 'b': c
= '\b'; break;
2052 case 't': c
= '\t'; break;
2057 static void xmon_rawdump (unsigned long adrs
, long ndump
)
2060 unsigned char temp
[16];
2062 for (n
= ndump
; n
> 0;) {
2064 nr
= mread(adrs
, temp
, r
);
2066 for (m
= 0; m
< r
; ++m
) {
2068 printf("%.2x", temp
[m
]);
2070 printf("%s", fault_chars
[fault_type
]);
2080 static void dump_one_paca(int cpu
)
2082 struct paca_struct
*p
;
2084 if (setjmp(bus_error_jmp
) != 0) {
2085 printf("*** Error dumping paca for cpu 0x%x!\n", cpu
);
2089 catch_memory_errors
= 1;
2094 printf("paca for cpu 0x%x @ %p:\n", cpu
, p
);
2096 printf(" %-*s = %s\n", 16, "possible", cpu_possible(cpu
) ? "yes" : "no");
2097 printf(" %-*s = %s\n", 16, "present", cpu_present(cpu
) ? "yes" : "no");
2098 printf(" %-*s = %s\n", 16, "online", cpu_online(cpu
) ? "yes" : "no");
2100 #define DUMP(paca, name, format) \
2101 printf(" %-*s = %#-*"format"\t(0x%lx)\n", 16, #name, 18, paca->name, \
2102 offsetof(struct paca_struct, name));
2104 DUMP(p
, lock_token
, "x");
2105 DUMP(p
, paca_index
, "x");
2106 DUMP(p
, kernel_toc
, "lx");
2107 DUMP(p
, kernelbase
, "lx");
2108 DUMP(p
, kernel_msr
, "lx");
2109 DUMP(p
, emergency_sp
, "p");
2110 #ifdef CONFIG_PPC_BOOK3S_64
2111 DUMP(p
, mc_emergency_sp
, "p");
2112 DUMP(p
, in_mce
, "x");
2114 DUMP(p
, data_offset
, "lx");
2115 DUMP(p
, hw_cpu_id
, "x");
2116 DUMP(p
, cpu_start
, "x");
2117 DUMP(p
, kexec_state
, "x");
2118 DUMP(p
, __current
, "p");
2119 DUMP(p
, kstack
, "lx");
2120 DUMP(p
, stab_rr
, "lx");
2121 DUMP(p
, saved_r1
, "lx");
2122 DUMP(p
, trap_save
, "x");
2123 DUMP(p
, soft_enabled
, "x");
2124 DUMP(p
, irq_happened
, "x");
2125 DUMP(p
, io_sync
, "x");
2126 DUMP(p
, irq_work_pending
, "x");
2127 DUMP(p
, nap_state_lost
, "x");
2131 catch_memory_errors
= 0;
2135 static void dump_all_pacas(void)
2139 if (num_possible_cpus() == 0) {
2140 printf("No possible cpus, use 'dp #' to dump individual cpus\n");
2144 for_each_possible_cpu(cpu
)
2148 static void dump_pacas(void)
2159 termch
= c
; /* Put c back, it wasn't 'a' */
2164 dump_one_paca(xmon_owner
);
2168 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
2169 || ('a' <= (c) && (c) <= 'f') \
2170 || ('A' <= (c) && (c) <= 'F'))
2185 if ((isxdigit(c
) && c
!= 'f' && c
!= 'd') || c
== '\n')
2187 scanhex((void *)&adrs
);
2194 else if (nidump
> MAX_DUMP
)
2196 adrs
+= ppc_inst_dump(adrs
, nidump
, 1);
2198 } else if (c
== 'l') {
2200 } else if (c
== 'r') {
2204 xmon_rawdump(adrs
, ndump
);
2211 else if (ndump
> MAX_DUMP
)
2213 prdump(adrs
, ndump
);
2220 prdump(unsigned long adrs
, long ndump
)
2222 long n
, m
, c
, r
, nr
;
2223 unsigned char temp
[16];
2225 for (n
= ndump
; n
> 0;) {
2229 nr
= mread(adrs
, temp
, r
);
2231 for (m
= 0; m
< r
; ++m
) {
2232 if ((m
& (sizeof(long) - 1)) == 0 && m
> 0)
2235 printf("%.2x", temp
[m
]);
2237 printf("%s", fault_chars
[fault_type
]);
2239 for (; m
< 16; ++m
) {
2240 if ((m
& (sizeof(long) - 1)) == 0)
2245 for (m
= 0; m
< r
; ++m
) {
2248 putchar(' ' <= c
&& c
<= '~'? c
: '.');
2261 typedef int (*instruction_dump_func
)(unsigned long inst
, unsigned long addr
);
2264 generic_inst_dump(unsigned long adr
, long count
, int praddr
,
2265 instruction_dump_func dump_func
)
2268 unsigned long first_adr
;
2269 unsigned long inst
, last_inst
= 0;
2270 unsigned char val
[4];
2273 for (first_adr
= adr
; count
> 0; --count
, adr
+= 4) {
2274 nr
= mread(adr
, val
, 4);
2277 const char *x
= fault_chars
[fault_type
];
2278 printf(REG
" %s%s%s%s\n", adr
, x
, x
, x
, x
);
2282 inst
= GETWORD(val
);
2283 if (adr
> first_adr
&& inst
== last_inst
) {
2293 printf(REG
" %.8x", adr
, inst
);
2295 dump_func(inst
, adr
);
2298 return adr
- first_adr
;
2302 ppc_inst_dump(unsigned long adr
, long count
, int praddr
)
2304 return generic_inst_dump(adr
, count
, praddr
, print_insn_powerpc
);
2308 print_address(unsigned long addr
)
2310 xmon_print_symbol(addr
, "\t# ", "");
2316 struct kmsg_dumper dumper
= { .active
= 1 };
2317 unsigned char buf
[128];
2320 if (setjmp(bus_error_jmp
) != 0) {
2321 printf("Error dumping printk buffer!\n");
2325 catch_memory_errors
= 1;
2328 kmsg_dump_rewind_nolock(&dumper
);
2329 while (kmsg_dump_get_line_nolock(&dumper
, false, buf
, sizeof(buf
), &len
)) {
2335 /* wait a little while to see if we get a machine check */
2337 catch_memory_errors
= 0;
2341 * Memory operations - move, set, print differences
2343 static unsigned long mdest
; /* destination address */
2344 static unsigned long msrc
; /* source address */
2345 static unsigned long mval
; /* byte value to set memory to */
2346 static unsigned long mcount
; /* # bytes to affect */
2347 static unsigned long mdiffs
; /* max # differences to print */
2352 scanhex((void *)&mdest
);
2353 if( termch
!= '\n' )
2355 scanhex((void *)(cmd
== 's'? &mval
: &msrc
));
2356 if( termch
!= '\n' )
2358 scanhex((void *)&mcount
);
2361 memmove((void *)mdest
, (void *)msrc
, mcount
);
2364 memset((void *)mdest
, mval
, mcount
);
2367 if( termch
!= '\n' )
2369 scanhex((void *)&mdiffs
);
2370 memdiffs((unsigned char *)mdest
, (unsigned char *)msrc
, mcount
, mdiffs
);
2376 memdiffs(unsigned char *p1
, unsigned char *p2
, unsigned nb
, unsigned maxpr
)
2381 for( n
= nb
; n
> 0; --n
)
2382 if( *p1
++ != *p2
++ )
2383 if( ++prt
<= maxpr
)
2384 printf("%.16x %.2x # %.16x %.2x\n", p1
- 1,
2385 p1
[-1], p2
- 1, p2
[-1]);
2387 printf("Total of %d differences\n", prt
);
2390 static unsigned mend
;
2391 static unsigned mask
;
2397 unsigned char val
[4];
2400 scanhex((void *)&mdest
);
2401 if (termch
!= '\n') {
2403 scanhex((void *)&mend
);
2404 if (termch
!= '\n') {
2406 scanhex((void *)&mval
);
2408 if (termch
!= '\n') termch
= 0;
2409 scanhex((void *)&mask
);
2413 for (a
= mdest
; a
< mend
; a
+= 4) {
2414 if (mread(a
, val
, 4) == 4
2415 && ((GETWORD(val
) ^ mval
) & mask
) == 0) {
2416 printf("%.16x: %.16x\n", a
, GETWORD(val
));
2423 static unsigned long mskip
= 0x1000;
2424 static unsigned long mlim
= 0xffffffff;
2434 if (termch
!= '\n') termch
= 0;
2436 if (termch
!= '\n') termch
= 0;
2439 for (a
= mdest
; a
< mlim
; a
+= mskip
) {
2440 ok
= mread(a
, &v
, 1);
2442 printf("%.8x .. ", a
);
2443 } else if (!ok
&& ook
)
2444 printf("%.8x\n", a
- mskip
);
2450 printf("%.8x\n", a
- mskip
);
2453 static void proccall(void)
2455 unsigned long args
[8];
2458 typedef unsigned long (*callfunc_t
)(unsigned long, unsigned long,
2459 unsigned long, unsigned long, unsigned long,
2460 unsigned long, unsigned long, unsigned long);
2463 if (!scanhex(&adrs
))
2467 for (i
= 0; i
< 8; ++i
)
2469 for (i
= 0; i
< 8; ++i
) {
2470 if (!scanhex(&args
[i
]) || termch
== '\n')
2474 func
= (callfunc_t
) adrs
;
2476 if (setjmp(bus_error_jmp
) == 0) {
2477 catch_memory_errors
= 1;
2479 ret
= func(args
[0], args
[1], args
[2], args
[3],
2480 args
[4], args
[5], args
[6], args
[7]);
2482 printf("return value is 0x%lx\n", ret
);
2484 printf("*** %x exception occurred\n", fault_except
);
2486 catch_memory_errors
= 0;
2489 /* Input scanning routines */
2500 while( c
== ' ' || c
== '\t' )
2506 static char *regnames
[N_PTREGS
] = {
2507 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2508 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2509 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2510 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2511 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2517 "trap", "dar", "dsisr", "res"
2521 scanhex(unsigned long *vp
)
2528 /* parse register name */
2532 for (i
= 0; i
< sizeof(regname
) - 1; ++i
) {
2541 for (i
= 0; i
< N_PTREGS
; ++i
) {
2542 if (strcmp(regnames
[i
], regname
) == 0) {
2543 if (xmon_regs
== NULL
) {
2544 printf("regs not available\n");
2547 *vp
= ((unsigned long *)xmon_regs
)[i
];
2551 printf("invalid register name '%%%s'\n", regname
);
2555 /* skip leading "0x" if any */
2569 } else if (c
== '$') {
2571 for (i
=0; i
<63; i
++) {
2581 if (setjmp(bus_error_jmp
) == 0) {
2582 catch_memory_errors
= 1;
2584 *vp
= kallsyms_lookup_name(tmpstr
);
2587 catch_memory_errors
= 0;
2589 printf("unknown symbol '%s'\n", tmpstr
);
2622 static int hexdigit(int c
)
2624 if( '0' <= c
&& c
<= '9' )
2626 if( 'A' <= c
&& c
<= 'F' )
2627 return c
- ('A' - 10);
2628 if( 'a' <= c
&& c
<= 'f' )
2629 return c
- ('a' - 10);
2634 getstring(char *s
, int size
)
2645 } while( c
!= ' ' && c
!= '\t' && c
!= '\n' );
2650 static char line
[256];
2651 static char *lineptr
;
2662 if (lineptr
== NULL
|| *lineptr
== 0) {
2663 if (xmon_gets(line
, sizeof(line
)) == NULL
) {
2673 take_input(char *str
)
2682 int type
= inchar();
2684 static char tmp
[64];
2689 xmon_print_symbol(addr
, ": ", "\n");
2694 if (setjmp(bus_error_jmp
) == 0) {
2695 catch_memory_errors
= 1;
2697 addr
= kallsyms_lookup_name(tmp
);
2699 printf("%s: %lx\n", tmp
, addr
);
2701 printf("Symbol '%s' not found.\n", tmp
);
2704 catch_memory_errors
= 0;
2711 /* Print an address in numeric and symbolic form (if possible) */
2712 static void xmon_print_symbol(unsigned long address
, const char *mid
,
2716 const char *name
= NULL
;
2717 unsigned long offset
, size
;
2719 printf(REG
, address
);
2720 if (setjmp(bus_error_jmp
) == 0) {
2721 catch_memory_errors
= 1;
2723 name
= kallsyms_lookup(address
, &size
, &offset
, &modname
,
2726 /* wait a little while to see if we get a machine check */
2730 catch_memory_errors
= 0;
2733 printf("%s%s+%#lx/%#lx", mid
, name
, offset
, size
);
2735 printf(" [%s]", modname
);
2737 printf("%s", after
);
2740 #ifdef CONFIG_PPC_BOOK3S_64
2741 void dump_segments(void)
2744 unsigned long esid
,vsid
,valid
;
2747 printf("SLB contents of cpu 0x%x\n", smp_processor_id());
2749 for (i
= 0; i
< mmu_slb_size
; i
++) {
2750 asm volatile("slbmfee %0,%1" : "=r" (esid
) : "r" (i
));
2751 asm volatile("slbmfev %0,%1" : "=r" (vsid
) : "r" (i
));
2752 valid
= (esid
& SLB_ESID_V
);
2753 if (valid
| esid
| vsid
) {
2754 printf("%02d %016lx %016lx", i
, esid
, vsid
);
2756 llp
= vsid
& SLB_VSID_LLP
;
2757 if (vsid
& SLB_VSID_B_1T
) {
2758 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
2760 (vsid
& ~SLB_VSID_B
) >> SLB_VSID_SHIFT_1T
,
2763 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
2765 (vsid
& ~SLB_VSID_B
) >> SLB_VSID_SHIFT
,
2775 #ifdef CONFIG_PPC_STD_MMU_32
2776 void dump_segments(void)
2781 for (i
= 0; i
< 16; ++i
)
2782 printf(" %x", mfsrin(i
));
2788 static void dump_tlb_44x(void)
2792 for (i
= 0; i
< PPC44x_TLB_SIZE
; i
++) {
2793 unsigned long w0
,w1
,w2
;
2794 asm volatile("tlbre %0,%1,0" : "=r" (w0
) : "r" (i
));
2795 asm volatile("tlbre %0,%1,1" : "=r" (w1
) : "r" (i
));
2796 asm volatile("tlbre %0,%1,2" : "=r" (w2
) : "r" (i
));
2797 printf("[%02x] %08x %08x %08x ", i
, w0
, w1
, w2
);
2798 if (w0
& PPC44x_TLB_VALID
) {
2799 printf("V %08x -> %01x%08x %c%c%c%c%c",
2800 w0
& PPC44x_TLB_EPN_MASK
,
2801 w1
& PPC44x_TLB_ERPN_MASK
,
2802 w1
& PPC44x_TLB_RPN_MASK
,
2803 (w2
& PPC44x_TLB_W
) ? 'W' : 'w',
2804 (w2
& PPC44x_TLB_I
) ? 'I' : 'i',
2805 (w2
& PPC44x_TLB_M
) ? 'M' : 'm',
2806 (w2
& PPC44x_TLB_G
) ? 'G' : 'g',
2807 (w2
& PPC44x_TLB_E
) ? 'E' : 'e');
2812 #endif /* CONFIG_44x */
2814 #ifdef CONFIG_PPC_BOOK3E
2815 static void dump_tlb_book3e(void)
2817 u32 mmucfg
, pidmask
, lpidmask
;
2819 int i
, tlb
, ntlbs
, pidsz
, lpidsz
, rasz
, lrat
= 0;
2821 static const char *pgsz_names
[] = {
2856 /* Gather some infos about the MMU */
2857 mmucfg
= mfspr(SPRN_MMUCFG
);
2858 mmu_version
= (mmucfg
& 3) + 1;
2859 ntlbs
= ((mmucfg
>> 2) & 3) + 1;
2860 pidsz
= ((mmucfg
>> 6) & 0x1f) + 1;
2861 lpidsz
= (mmucfg
>> 24) & 0xf;
2862 rasz
= (mmucfg
>> 16) & 0x7f;
2863 if ((mmu_version
> 1) && (mmucfg
& 0x10000))
2865 printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n",
2866 mmu_version
, ntlbs
, pidsz
, lpidsz
, rasz
);
2867 pidmask
= (1ul << pidsz
) - 1;
2868 lpidmask
= (1ul << lpidsz
) - 1;
2869 ramask
= (1ull << rasz
) - 1;
2871 for (tlb
= 0; tlb
< ntlbs
; tlb
++) {
2873 int nent
, assoc
, new_cc
= 1;
2874 printf("TLB %d:\n------\n", tlb
);
2877 tlbcfg
= mfspr(SPRN_TLB0CFG
);
2880 tlbcfg
= mfspr(SPRN_TLB1CFG
);
2883 tlbcfg
= mfspr(SPRN_TLB2CFG
);
2886 tlbcfg
= mfspr(SPRN_TLB3CFG
);
2889 printf("Unsupported TLB number !\n");
2892 nent
= tlbcfg
& 0xfff;
2893 assoc
= (tlbcfg
>> 24) & 0xff;
2894 for (i
= 0; i
< nent
; i
++) {
2895 u32 mas0
= MAS0_TLBSEL(tlb
);
2896 u32 mas1
= MAS1_TSIZE(BOOK3E_PAGESZ_4K
);
2899 int esel
= i
, cc
= i
;
2907 mas0
|= MAS0_ESEL(esel
);
2908 mtspr(SPRN_MAS0
, mas0
);
2909 mtspr(SPRN_MAS1
, mas1
);
2910 mtspr(SPRN_MAS2
, mas2
);
2911 asm volatile("tlbre 0,0,0" : : : "memory");
2912 mas1
= mfspr(SPRN_MAS1
);
2913 mas2
= mfspr(SPRN_MAS2
);
2914 mas7_mas3
= mfspr(SPRN_MAS7_MAS3
);
2915 if (assoc
&& (i
% assoc
) == 0)
2917 if (!(mas1
& MAS1_VALID
))
2920 printf("%04x- ", i
);
2922 printf("%04x-%c", cc
, 'A' + esel
);
2924 printf(" |%c", 'A' + esel
);
2926 printf(" %016llx %04x %s %c%c AS%c",
2928 (mas1
>> 16) & 0x3fff,
2929 pgsz_names
[(mas1
>> 7) & 0x1f],
2930 mas1
& MAS1_IND
? 'I' : ' ',
2931 mas1
& MAS1_IPROT
? 'P' : ' ',
2932 mas1
& MAS1_TS
? '1' : '0');
2933 printf(" %c%c%c%c%c%c%c",
2934 mas2
& MAS2_X0
? 'a' : ' ',
2935 mas2
& MAS2_X1
? 'v' : ' ',
2936 mas2
& MAS2_W
? 'w' : ' ',
2937 mas2
& MAS2_I
? 'i' : ' ',
2938 mas2
& MAS2_M
? 'm' : ' ',
2939 mas2
& MAS2_G
? 'g' : ' ',
2940 mas2
& MAS2_E
? 'e' : ' ');
2941 printf(" %016llx", mas7_mas3
& ramask
& ~0x7ffull
);
2942 if (mas1
& MAS1_IND
)
2944 pgsz_names
[(mas7_mas3
>> 1) & 0x1f]);
2946 printf(" U%c%c%c S%c%c%c\n",
2947 mas7_mas3
& MAS3_UX
? 'x' : ' ',
2948 mas7_mas3
& MAS3_UW
? 'w' : ' ',
2949 mas7_mas3
& MAS3_UR
? 'r' : ' ',
2950 mas7_mas3
& MAS3_SX
? 'x' : ' ',
2951 mas7_mas3
& MAS3_SW
? 'w' : ' ',
2952 mas7_mas3
& MAS3_SR
? 'r' : ' ');
2956 #endif /* CONFIG_PPC_BOOK3E */
2958 static void xmon_init(int enable
)
2962 __debugger_ipi
= xmon_ipi
;
2963 __debugger_bpt
= xmon_bpt
;
2964 __debugger_sstep
= xmon_sstep
;
2965 __debugger_iabr_match
= xmon_iabr_match
;
2966 __debugger_break_match
= xmon_break_match
;
2967 __debugger_fault_handler
= xmon_fault_handler
;
2970 __debugger_ipi
= NULL
;
2971 __debugger_bpt
= NULL
;
2972 __debugger_sstep
= NULL
;
2973 __debugger_iabr_match
= NULL
;
2974 __debugger_break_match
= NULL
;
2975 __debugger_fault_handler
= NULL
;
2979 #ifdef CONFIG_MAGIC_SYSRQ
2980 static void sysrq_handle_xmon(int key
)
2982 /* ensure xmon is enabled */
2984 debugger(get_irq_regs());
2987 static struct sysrq_key_op sysrq_xmon_op
= {
2988 .handler
= sysrq_handle_xmon
,
2989 .help_msg
= "xmon(x)",
2990 .action_msg
= "Entering xmon",
2993 static int __init
setup_xmon_sysrq(void)
2995 register_sysrq_key('x', &sysrq_xmon_op
);
2998 __initcall(setup_xmon_sysrq
);
2999 #endif /* CONFIG_MAGIC_SYSRQ */
3001 static int __initdata xmon_early
, xmon_off
;
3003 static int __init
early_parse_xmon(char *p
)
3005 if (!p
|| strncmp(p
, "early", 5) == 0) {
3006 /* just "xmon" is equivalent to "xmon=early" */
3009 } else if (strncmp(p
, "on", 2) == 0)
3011 else if (strncmp(p
, "off", 3) == 0)
3013 else if (strncmp(p
, "nobt", 4) == 0)
3014 xmon_no_auto_backtrace
= 1;
3020 early_param("xmon", early_parse_xmon
);
3022 void __init
xmon_setup(void)
3024 #ifdef CONFIG_XMON_DEFAULT
3032 #ifdef CONFIG_SPU_BASE
3036 u64 saved_mfc_sr1_RW
;
3037 u32 saved_spu_runcntl_RW
;
3038 unsigned long dump_addr
;
3042 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
3044 static struct spu_info spu_info
[XMON_NUM_SPUS
];
3046 void xmon_register_spus(struct list_head
*list
)
3050 list_for_each_entry(spu
, list
, full_list
) {
3051 if (spu
->number
>= XMON_NUM_SPUS
) {
3056 spu_info
[spu
->number
].spu
= spu
;
3057 spu_info
[spu
->number
].stopped_ok
= 0;
3058 spu_info
[spu
->number
].dump_addr
= (unsigned long)
3059 spu_info
[spu
->number
].spu
->local_store
;
3063 static void stop_spus(void)
3069 for (i
= 0; i
< XMON_NUM_SPUS
; i
++) {
3070 if (!spu_info
[i
].spu
)
3073 if (setjmp(bus_error_jmp
) == 0) {
3074 catch_memory_errors
= 1;
3077 spu
= spu_info
[i
].spu
;
3079 spu_info
[i
].saved_spu_runcntl_RW
=
3080 in_be32(&spu
->problem
->spu_runcntl_RW
);
3082 tmp
= spu_mfc_sr1_get(spu
);
3083 spu_info
[i
].saved_mfc_sr1_RW
= tmp
;
3085 tmp
&= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK
;
3086 spu_mfc_sr1_set(spu
, tmp
);
3091 spu_info
[i
].stopped_ok
= 1;
3093 printf("Stopped spu %.2d (was %s)\n", i
,
3094 spu_info
[i
].saved_spu_runcntl_RW
?
3095 "running" : "stopped");
3097 catch_memory_errors
= 0;
3098 printf("*** Error stopping spu %.2d\n", i
);
3100 catch_memory_errors
= 0;
3104 static void restart_spus(void)
3109 for (i
= 0; i
< XMON_NUM_SPUS
; i
++) {
3110 if (!spu_info
[i
].spu
)
3113 if (!spu_info
[i
].stopped_ok
) {
3114 printf("*** Error, spu %d was not successfully stopped"
3115 ", not restarting\n", i
);
3119 if (setjmp(bus_error_jmp
) == 0) {
3120 catch_memory_errors
= 1;
3123 spu
= spu_info
[i
].spu
;
3124 spu_mfc_sr1_set(spu
, spu_info
[i
].saved_mfc_sr1_RW
);
3125 out_be32(&spu
->problem
->spu_runcntl_RW
,
3126 spu_info
[i
].saved_spu_runcntl_RW
);
3131 printf("Restarted spu %.2d\n", i
);
3133 catch_memory_errors
= 0;
3134 printf("*** Error restarting spu %.2d\n", i
);
3136 catch_memory_errors
= 0;
3140 #define DUMP_WIDTH 23
3141 #define DUMP_VALUE(format, field, value) \
3143 if (setjmp(bus_error_jmp) == 0) { \
3144 catch_memory_errors = 1; \
3146 printf(" %-*s = "format"\n", DUMP_WIDTH, \
3151 catch_memory_errors = 0; \
3152 printf(" %-*s = *** Error reading field.\n", \
3153 DUMP_WIDTH, #field); \
3155 catch_memory_errors = 0; \
3158 #define DUMP_FIELD(obj, format, field) \
3159 DUMP_VALUE(format, field, obj->field)
3161 static void dump_spu_fields(struct spu
*spu
)
3163 printf("Dumping spu fields at address %p:\n", spu
);
3165 DUMP_FIELD(spu
, "0x%x", number
);
3166 DUMP_FIELD(spu
, "%s", name
);
3167 DUMP_FIELD(spu
, "0x%lx", local_store_phys
);
3168 DUMP_FIELD(spu
, "0x%p", local_store
);
3169 DUMP_FIELD(spu
, "0x%lx", ls_size
);
3170 DUMP_FIELD(spu
, "0x%x", node
);
3171 DUMP_FIELD(spu
, "0x%lx", flags
);
3172 DUMP_FIELD(spu
, "%d", class_0_pending
);
3173 DUMP_FIELD(spu
, "0x%lx", class_0_dar
);
3174 DUMP_FIELD(spu
, "0x%lx", class_1_dar
);
3175 DUMP_FIELD(spu
, "0x%lx", class_1_dsisr
);
3176 DUMP_FIELD(spu
, "0x%lx", irqs
[0]);
3177 DUMP_FIELD(spu
, "0x%lx", irqs
[1]);
3178 DUMP_FIELD(spu
, "0x%lx", irqs
[2]);
3179 DUMP_FIELD(spu
, "0x%x", slb_replace
);
3180 DUMP_FIELD(spu
, "%d", pid
);
3181 DUMP_FIELD(spu
, "0x%p", mm
);
3182 DUMP_FIELD(spu
, "0x%p", ctx
);
3183 DUMP_FIELD(spu
, "0x%p", rq
);
3184 DUMP_FIELD(spu
, "0x%p", timestamp
);
3185 DUMP_FIELD(spu
, "0x%lx", problem_phys
);
3186 DUMP_FIELD(spu
, "0x%p", problem
);
3187 DUMP_VALUE("0x%x", problem
->spu_runcntl_RW
,
3188 in_be32(&spu
->problem
->spu_runcntl_RW
));
3189 DUMP_VALUE("0x%x", problem
->spu_status_R
,
3190 in_be32(&spu
->problem
->spu_status_R
));
3191 DUMP_VALUE("0x%x", problem
->spu_npc_RW
,
3192 in_be32(&spu
->problem
->spu_npc_RW
));
3193 DUMP_FIELD(spu
, "0x%p", priv2
);
3194 DUMP_FIELD(spu
, "0x%p", pdata
);
3198 spu_inst_dump(unsigned long adr
, long count
, int praddr
)
3200 return generic_inst_dump(adr
, count
, praddr
, print_insn_spu
);
3203 static void dump_spu_ls(unsigned long num
, int subcmd
)
3205 unsigned long offset
, addr
, ls_addr
;
3207 if (setjmp(bus_error_jmp
) == 0) {
3208 catch_memory_errors
= 1;
3210 ls_addr
= (unsigned long)spu_info
[num
].spu
->local_store
;
3214 catch_memory_errors
= 0;
3215 printf("*** Error: accessing spu info for spu %d\n", num
);
3218 catch_memory_errors
= 0;
3220 if (scanhex(&offset
))
3221 addr
= ls_addr
+ offset
;
3223 addr
= spu_info
[num
].dump_addr
;
3225 if (addr
>= ls_addr
+ LS_SIZE
) {
3226 printf("*** Error: address outside of local store\n");
3232 addr
+= spu_inst_dump(addr
, 16, 1);
3242 spu_info
[num
].dump_addr
= addr
;
3245 static int do_spu_cmd(void)
3247 static unsigned long num
= 0;
3248 int cmd
, subcmd
= 0;
3260 if (isxdigit(subcmd
) || subcmd
== '\n')
3264 if (num
>= XMON_NUM_SPUS
|| !spu_info
[num
].spu
) {
3265 printf("*** Error: invalid spu number\n");
3271 dump_spu_fields(spu_info
[num
].spu
);
3274 dump_spu_ls(num
, subcmd
);
3285 #else /* ! CONFIG_SPU_BASE */
3286 static int do_spu_cmd(void)