1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Routines providing a simple monitor for use on the PowerMac.
5 * Copyright (C) 1996-2005 Paul Mackerras.
6 * Copyright (C) 2001 PPC64 Team, IBM Corp
7 * Copyrignt (C) 2006 Michael Ellerman, IBM Corp
10 #include <linux/kernel.h>
11 #include <linux/errno.h>
12 #include <linux/sched/signal.h>
13 #include <linux/smp.h>
15 #include <linux/reboot.h>
16 #include <linux/delay.h>
17 #include <linux/kallsyms.h>
18 #include <linux/kmsg_dump.h>
19 #include <linux/cpumask.h>
20 #include <linux/export.h>
21 #include <linux/sysrq.h>
22 #include <linux/interrupt.h>
23 #include <linux/irq.h>
24 #include <linux/bug.h>
25 #include <linux/nmi.h>
26 #include <linux/ctype.h>
27 #include <linux/highmem.h>
28 #include <linux/security.h>
29 #include <linux/debugfs.h>
31 #include <asm/ptrace.h>
33 #include <asm/string.h>
34 #include <asm/machdep.h>
36 #include <asm/processor.h>
38 #include <asm/mmu_context.h>
39 #include <asm/plpar_wrappers.h>
40 #include <asm/cputable.h>
42 #include <asm/sstep.h>
43 #include <asm/irq_regs.h>
45 #include <asm/spu_priv1.h>
46 #include <asm/setjmp.h>
48 #include <asm/debug.h>
49 #include <asm/hw_breakpoint.h>
52 #include <asm/firmware.h>
53 #include <asm/code-patching.h>
54 #include <asm/sections.h>
56 #include <asm/interrupt.h>
59 #include <asm/hvcall.h>
61 #include <asm/lppaca.h>
66 #include "xmon_bpts.h"
69 static cpumask_t cpus_in_xmon = CPU_MASK_NONE;
70 static unsigned long xmon_taken = 1;
71 static int xmon_owner;
73 static int xmon_batch;
74 static unsigned long xmon_batch_start_cpu;
75 static cpumask_t xmon_batch_cpus = CPU_MASK_NONE;
78 #endif /* CONFIG_SMP */
80 static unsigned long in_xmon __read_mostly = 0;
81 static int xmon_on = IS_ENABLED(CONFIG_XMON_DEFAULT);
82 static bool xmon_is_ro = IS_ENABLED(CONFIG_XMON_DEFAULT_RO_MODE);
84 static unsigned long adrs;
86 #define MAX_DUMP (64 * 1024)
87 static unsigned long ndump = 64;
88 #define MAX_IDUMP (MAX_DUMP >> 2)
89 static unsigned long nidump = 16;
90 static unsigned long ncsum = 4096;
92 static char tmpstr[KSYM_NAME_LEN];
93 static int tracing_enabled;
95 static long bus_error_jmp[JMP_BUF_LEN];
96 static int catch_memory_errors;
97 static int catch_spr_faults;
98 static long *xmon_fault_jmp[NR_CPUS];
100 /* Breakpoint stuff */
102 unsigned long address;
109 /* Bits in bpt.enabled */
114 static struct bpt bpts[NBPTS];
115 static struct bpt dabr[HBP_NUM_MAX];
116 static struct bpt *iabr;
117 static unsigned int bpinstr = PPC_RAW_TRAP();
119 #define BP_NUM(bp) ((bp) - bpts + 1)
122 static int cmds(struct pt_regs *);
123 static int mread(unsigned long, void *, int);
124 static int mwrite(unsigned long, void *, int);
125 static int mread_instr(unsigned long, ppc_inst_t *);
126 static int handle_fault(struct pt_regs *);
127 static void byterev(unsigned char *, int);
128 static void memex(void);
129 static int bsesc(void);
130 static void dump(void);
131 static void show_pte(unsigned long);
132 static void prdump(unsigned long, long);
133 static int ppc_inst_dump(unsigned long, long, int);
134 static void dump_log_buf(void);
137 static int xmon_switch_cpu(unsigned long);
138 static int xmon_batch_next_cpu(void);
139 static int batch_cmds(struct pt_regs *);
142 #ifdef CONFIG_PPC_POWERNV
143 static void dump_opal_msglog(void);
145 static inline void dump_opal_msglog(void)
147 printf("Machine is not running OPAL firmware.\n");
151 static void backtrace(struct pt_regs *);
152 static void excprint(struct pt_regs *);
153 static void prregs(struct pt_regs *);
154 static void memops(int);
155 static void memlocate(void);
156 static void memzcan(void);
157 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
159 int scanhex(unsigned long *valp);
160 static void scannl(void);
161 static int hexdigit(int);
162 void getstring(char *, int);
163 static void flush_input(void);
164 static int inchar(void);
165 static void take_input(char *);
166 static int read_spr(int, unsigned long *);
167 static void write_spr(int, unsigned long);
168 static void super_regs(void);
169 static void remove_bpts(void);
170 static void insert_bpts(void);
171 static void remove_cpu_bpts(void);
172 static void insert_cpu_bpts(void);
173 static struct bpt *at_breakpoint(unsigned long pc);
174 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
175 static int do_step(struct pt_regs *);
176 static void bpt_cmds(void);
177 static void cacheflush(void);
178 static int cpu_cmd(void);
179 static void csum(void);
180 static void bootcmds(void);
181 static void proccall(void);
182 static void show_tasks(void);
183 void dump_segments(void);
184 static void symbol_lookup(void);
185 static void xmon_show_stack(unsigned long sp, unsigned long lr,
187 static void xmon_print_symbol(unsigned long address, const char *mid,
189 static const char *getvecname(unsigned long vec);
191 static int do_spu_cmd(void);
194 static void dump_tlb_44x(void);
196 #ifdef CONFIG_PPC_BOOK3E_64
197 static void dump_tlb_book3e(void);
200 static void clear_all_bpt(void);
208 #ifdef __LITTLE_ENDIAN__
209 #define GETWORD(v) (((v)[3] << 24) + ((v)[2] << 16) + ((v)[1] << 8) + (v)[0])
211 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
214 static const char *xmon_ro_msg = "Operation disabled: xmon in read-only mode\n";
216 static char *help_string = "\
218 b show breakpoints\n\
219 bd set data breakpoint\n\
220 bi set instruction breakpoint\n\
221 bc clear breakpoint\n"
224 c print cpus stopped in xmon\n\
225 c# try to switch to cpu number h (in hex)\n\
226 c# $ run command '$' (one of 'r','S' or 't') on all cpus in xmon\n"
231 d1 dump 1 byte values\n\
232 d2 dump 2 byte values\n\
233 d4 dump 4 byte values\n\
234 d8 dump 8 byte values\n\
235 di dump instructions\n\
236 df dump float values\n\
237 dd dump double values\n\
238 dl dump the kernel log buffer\n"
239 #ifdef CONFIG_PPC_POWERNV
241 do dump the OPAL message log\n"
245 dp[#] dump paca for current cpu, or cpu #\n\
246 dpa dump paca for all possible cpus\n"
249 dr dump stream of raw bytes\n\
250 dv dump virtual address translation \n\
251 dt dump the tracing buffers (uses printk)\n\
252 dtc dump the tracing buffers for current CPU (uses printk)\n\
254 #ifdef CONFIG_PPC_POWERNV
255 " dx# dump xive on CPU #\n\
256 dxi# dump xive irq state #\n\
257 dxa dump xive on all CPUs\n"
259 " e print exception information\n\
261 la lookup symbol+offset of specified address\n\
262 ls lookup address of specified symbol\n\
263 lp s [#] lookup address of percpu symbol s for current cpu, or cpu #\n\
264 m examine/change memory\n\
265 mm move a block of memory\n\
266 ms set a block of memory\n\
267 md compare two blocks of memory\n\
268 ml locate a block of memory\n\
269 mz zero a block of memory\n\
270 mi show information about memory allocation\n\
271 p call a procedure\n\
272 P list processes/tasks\n\
275 #ifdef CONFIG_SPU_BASE
276 " ss stop execution on all spus\n\
277 sr restore execution on stopped spus\n\
278 sf # dump spu fields for spu # (in hex)\n\
279 sd # dump spu local store for spu # (in hex)\n\
280 sdi # disassemble spu local store for spu # (in hex)\n"
282 " S print special registers\n\
285 Sw #v write v to SPR #\n\
287 x exit monitor and recover\n\
288 X exit monitor and don't recover\n"
289 #if defined(CONFIG_PPC_BOOK3S_64)
290 " u dump segment table or SLB\n"
291 #elif defined(CONFIG_PPC_BOOK3S_32)
292 " u dump segment registers\n"
293 #elif defined(CONFIG_44x) || defined(CONFIG_PPC_BOOK3E_64)
296 " U show uptime information\n"
298 " # n limit output to n lines per page (for dp, dpa, dl)\n"
303 #ifdef CONFIG_SECURITY
304 static bool xmon_is_locked_down(void)
306 static bool lockdown;
309 lockdown = !!security_locked_down(LOCKDOWN_XMON_RW);
311 printf("xmon: Disabled due to kernel lockdown\n");
317 xmon_is_ro = !!security_locked_down(LOCKDOWN_XMON_WR);
319 printf("xmon: Read-only due to kernel lockdown\n");
324 #else /* CONFIG_SECURITY */
325 static inline bool xmon_is_locked_down(void)
331 static struct pt_regs *xmon_regs;
333 static inline void sync(void)
335 asm volatile("sync; isync");
338 static inline void cflush(void *p)
340 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
343 static inline void cinval(void *p)
345 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
349 * write_ciabr() - write the CIABR SPR
350 * @ciabr: The value to write.
352 * This function writes a value to the CIARB register either directly
353 * through mtspr instruction if the kernel is in HV privilege mode or
354 * call a hypervisor function to achieve the same in case the kernel
355 * is in supervisor privilege mode.
357 static void write_ciabr(unsigned long ciabr)
359 if (!cpu_has_feature(CPU_FTR_ARCH_207S))
362 if (cpu_has_feature(CPU_FTR_HVMODE)) {
363 mtspr(SPRN_CIABR, ciabr);
366 plpar_set_ciabr(ciabr);
370 * set_ciabr() - set the CIABR
371 * @addr: The value to set.
373 * This function sets the correct privilege value into the HW
374 * breakpoint address before writing it up in the CIABR register.
376 static void set_ciabr(unsigned long addr)
380 if (cpu_has_feature(CPU_FTR_HVMODE))
381 addr |= CIABR_PRIV_HYPER;
383 addr |= CIABR_PRIV_SUPER;
388 * Disable surveillance (the service processor watchdog function)
389 * while we are in xmon.
390 * XXX we should re-enable it when we leave. :)
392 #define SURVEILLANCE_TOKEN 9000
394 static inline void disable_surveillance(void)
396 #ifdef CONFIG_PPC_PSERIES
397 /* Since this can't be a module, args should end up below 4GB. */
398 static struct rtas_args args;
399 const s32 token = rtas_function_token(RTAS_FN_SET_INDICATOR);
402 * At this point we have got all the cpus we can into
403 * xmon, so there is hopefully no other cpu calling RTAS
404 * at the moment, even though we don't take rtas.lock.
405 * If we did try to take rtas.lock there would be a
406 * real possibility of deadlock.
408 if (token == RTAS_UNKNOWN_SERVICE)
411 rtas_call_unlocked(&args, token, 3, 1, NULL,
412 SURVEILLANCE_TOKEN, 0, 0);
414 #endif /* CONFIG_PPC_PSERIES */
418 static int xmon_speaker;
420 static void get_output_lock(void)
422 int me = smp_processor_id() + 0x100;
423 int last_speaker = 0, prev;
426 if (xmon_speaker == me)
430 last_speaker = cmpxchg(&xmon_speaker, 0, me);
431 if (last_speaker == 0)
435 * Wait a full second for the lock, we might be on a slow
436 * console, but check every 100us.
439 while (xmon_speaker == last_speaker) {
445 /* hostile takeover */
446 prev = cmpxchg(&xmon_speaker, last_speaker, me);
447 if (prev == last_speaker)
454 static void release_output_lock(void)
459 int cpus_are_in_xmon(void)
461 return !cpumask_empty(&cpus_in_xmon);
464 static bool wait_for_other_cpus(int ncpus)
466 unsigned long timeout;
468 /* We wait for 2s, which is a metric "little while" */
469 for (timeout = 20000; timeout != 0; --timeout) {
470 if (cpumask_weight(&cpus_in_xmon) >= ncpus)
478 #else /* CONFIG_SMP */
479 static inline void get_output_lock(void) {}
480 static inline void release_output_lock(void) {}
483 static void xmon_touch_watchdogs(void)
485 touch_softlockup_watchdog_sync();
486 rcu_cpu_stall_reset();
487 touch_nmi_watchdog();
490 static int xmon_core(struct pt_regs *regs, volatile int fromipi)
492 volatile int cmd = 0;
493 struct bpt *volatile bp;
494 long recurse_jmp[JMP_BUF_LEN];
496 unsigned long offset;
503 local_irq_save(flags);
506 locked_down = xmon_is_locked_down();
509 tracing_enabled = tracing_is_on();
513 bp = in_breakpoint_table(regs->nip, &offset);
515 regs_set_return_ip(regs, bp->address + offset);
516 atomic_dec(&bp->ref_count);
522 cpu = smp_processor_id();
523 if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
525 * We catch SPR read/write faults here because the 0x700, 0xf60
526 * etc. handlers don't call debugger_fault_handler().
528 if (catch_spr_faults)
529 longjmp(bus_error_jmp, 1);
532 printf("cpu 0x%x: Exception %lx %s in xmon, "
533 "returning to main loop\n",
534 cpu, regs->trap, getvecname(TRAP(regs)));
535 release_output_lock();
536 longjmp(xmon_fault_jmp[cpu], 1);
539 if (setjmp(recurse_jmp) != 0) {
540 if (!in_xmon || !xmon_gate) {
542 printf("xmon: WARNING: bad recursive fault "
543 "on cpu 0x%x\n", cpu);
544 release_output_lock();
547 secondary = !(xmon_taken && cpu == xmon_owner);
551 xmon_fault_jmp[cpu] = recurse_jmp;
554 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT))
555 bp = at_breakpoint(regs->nip);
556 if (bp || regs_is_unrecoverable(regs))
564 printf("cpu 0x%x stopped at breakpoint 0x%tx (",
566 xmon_print_symbol(regs->nip, " ", ")\n");
568 if (regs_is_unrecoverable(regs))
569 printf("WARNING: exception is not recoverable, "
571 release_output_lock();
574 cpumask_set_cpu(cpu, &cpus_in_xmon);
579 while (secondary && !xmon_gate) {
585 secondary = test_and_set_bit(0, &in_xmon);
588 touch_nmi_watchdog();
592 if (!secondary && !xmon_gate) {
593 /* we are the first cpu to come in */
594 /* interrupt other cpu(s) */
595 int ncpus = num_online_cpus();
601 * A system reset (trap == 0x100) can be triggered on
602 * all CPUs, so when we come in via 0x100 try waiting
603 * for the other CPUs to come in before we send the
604 * debugger break (IPI). This is similar to
605 * crash_kexec_secondary().
607 if (TRAP(regs) != INTERRUPT_SYSTEM_RESET || !wait_for_other_cpus(ncpus))
608 smp_send_debugger_break();
610 wait_for_other_cpus(ncpus);
613 disable_surveillance();
616 /* for breakpoint or single step, print curr insn */
617 if (bp || TRAP(regs) == INTERRUPT_TRACE)
618 ppc_inst_dump(regs->nip, 1, 0);
619 printf("enter ? for help\n");
625 touch_nmi_watchdog();
632 if (cpu == xmon_owner) {
633 if (!test_and_set_bit(0, &xmon_taken)) {
639 while (cpu == xmon_owner)
643 touch_nmi_watchdog();
648 cmd = batch_cmds(regs);
650 if (!locked_down && cmd)
652 if (locked_down || cmd != 0) {
660 /* have switched to some other cpu */
665 cpumask_clear_cpu(cpu, &cpus_in_xmon);
666 xmon_fault_jmp[cpu] = NULL;
668 /* UP is simple... */
670 printf("Exception %lx %s in xmon, returning to main loop\n",
671 regs->trap, getvecname(TRAP(regs)));
672 longjmp(xmon_fault_jmp[0], 1);
674 if (setjmp(recurse_jmp) == 0) {
675 xmon_fault_jmp[0] = recurse_jmp;
679 bp = at_breakpoint(regs->nip);
681 printf("Stopped at breakpoint %tx (", BP_NUM(bp));
682 xmon_print_symbol(regs->nip, " ", ")\n");
684 if (regs_is_unrecoverable(regs))
685 printf("WARNING: exception is not recoverable, "
688 disable_surveillance();
690 /* for breakpoint or single step, print current insn */
691 if (bp || TRAP(regs) == INTERRUPT_TRACE)
692 ppc_inst_dump(regs->nip, 1, 0);
693 printf("enter ? for help\n");
705 if (regs->msr & MSR_DE) {
706 bp = at_breakpoint(regs->nip);
708 regs_set_return_ip(regs, (unsigned long) &bp->instr[0]);
709 atomic_inc(&bp->ref_count);
713 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
714 bp = at_breakpoint(regs->nip);
716 int stepped = emulate_step(regs, ppc_inst_read(bp->instr));
718 regs_set_return_ip(regs, (unsigned long) &bp->instr[0]);
719 atomic_inc(&bp->ref_count);
720 } else if (stepped < 0) {
721 printf("Couldn't single-step %s instruction\n",
722 IS_RFID(ppc_inst_read(bp->instr))? "rfid": "mtmsrd");
732 xmon_touch_watchdogs();
733 local_irq_restore(flags);
735 return cmd != 'X' && cmd != EOF;
738 int xmon(struct pt_regs *excp)
743 ppc_save_regs(®s);
747 return xmon_core(excp, 0);
751 irqreturn_t xmon_irq(int irq, void *d)
754 local_irq_save(flags);
755 printf("Keyboard interrupt\n");
756 xmon(get_irq_regs());
757 local_irq_restore(flags);
761 static int xmon_bpt(struct pt_regs *regs)
764 unsigned long offset;
766 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
769 /* Are we at the trap at bp->instr[1] for some bp? */
770 bp = in_breakpoint_table(regs->nip, &offset);
771 if (bp != NULL && (offset == 4 || offset == 8)) {
772 regs_set_return_ip(regs, bp->address + offset);
773 atomic_dec(&bp->ref_count);
777 /* Are we at a breakpoint? */
778 bp = at_breakpoint(regs->nip);
787 static int xmon_sstep(struct pt_regs *regs)
795 static int xmon_break_match(struct pt_regs *regs)
799 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
801 for (i = 0; i < nr_wp_slots(); i++) {
812 static int xmon_iabr_match(struct pt_regs *regs)
814 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
822 static int xmon_ipi(struct pt_regs *regs)
825 if (in_xmon && !cpumask_test_cpu(smp_processor_id(), &cpus_in_xmon))
831 static int xmon_fault_handler(struct pt_regs *regs)
834 unsigned long offset;
836 if (in_xmon && catch_memory_errors)
837 handle_fault(regs); /* doesn't return */
839 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
840 bp = in_breakpoint_table(regs->nip, &offset);
842 regs_set_return_ip(regs, bp->address + offset);
843 atomic_dec(&bp->ref_count);
850 /* Force enable xmon if not already enabled */
851 static inline void force_enable_xmon(void)
853 /* Enable xmon hooks if needed */
855 printf("xmon: Enabling debugger hooks\n");
860 static struct bpt *at_breakpoint(unsigned long pc)
863 struct bpt *volatile bp;
866 for (i = 0; i < NBPTS; ++i, ++bp)
867 if (bp->enabled && pc == bp->address)
872 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
876 off = nip - (unsigned long)bpt_table;
877 if (off >= sizeof(bpt_table))
879 *offp = off & (BPT_SIZE - 1);
882 return bpts + (off / BPT_SIZE);
885 static struct bpt *new_breakpoint(unsigned long a)
890 bp = at_breakpoint(a);
894 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
895 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
897 bp->instr = (void *)(bpt_table + ((bp - bpts) * BPT_WORDS));
902 printf("Sorry, no free breakpoints. Please clear one first.\n");
906 static void insert_bpts(void)
909 ppc_inst_t instr, instr2;
910 struct bpt *bp, *bp2;
913 for (i = 0; i < NBPTS; ++i, ++bp) {
914 if ((bp->enabled & (BP_TRAP|BP_CIABR)) == 0)
916 if (!mread_instr(bp->address, &instr)) {
917 printf("Couldn't read instruction at %lx, "
918 "disabling breakpoint there\n", bp->address);
922 if (!can_single_step(ppc_inst_val(instr))) {
923 printf("Breakpoint at %lx is on an instruction that can't be single stepped, disabling it\n",
929 * Check the address is not a suffix by looking for a prefix in
932 if (mread_instr(bp->address - 4, &instr2) == 8) {
933 printf("Breakpoint at %lx is on the second word of a prefixed instruction, disabling it\n",
939 * We might still be a suffix - if the prefix has already been
940 * replaced by a breakpoint we won't catch it with the above
943 bp2 = at_breakpoint(bp->address - 4);
944 if (bp2 && ppc_inst_prefixed(ppc_inst_read(bp2->instr))) {
945 printf("Breakpoint at %lx is on the second word of a prefixed instruction, disabling it\n",
951 patch_instruction(bp->instr, instr);
952 patch_instruction(ppc_inst_next(bp->instr, bp->instr),
954 if (bp->enabled & BP_CIABR)
956 if (patch_instruction((u32 *)bp->address,
957 ppc_inst(bpinstr)) != 0) {
958 printf("Couldn't write instruction at %lx, "
959 "disabling breakpoint there\n", bp->address);
960 bp->enabled &= ~BP_TRAP;
966 static void insert_cpu_bpts(void)
969 struct arch_hw_breakpoint brk;
971 for (i = 0; i < nr_wp_slots(); i++) {
972 if (dabr[i].enabled) {
973 brk.address = dabr[i].address;
974 brk.type = (dabr[i].enabled & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL;
977 __set_breakpoint(i, &brk);
982 set_ciabr(iabr->address);
985 static void remove_bpts(void)
992 for (i = 0; i < NBPTS; ++i, ++bp) {
993 if ((bp->enabled & (BP_TRAP|BP_CIABR)) != BP_TRAP)
995 if (mread_instr(bp->address, &instr)
996 && ppc_inst_equal(instr, ppc_inst(bpinstr))
997 && patch_instruction(
998 (u32 *)bp->address, ppc_inst_read(bp->instr)) != 0)
999 printf("Couldn't remove breakpoint at %lx\n",
1004 static void remove_cpu_bpts(void)
1006 hw_breakpoint_disable();
1010 /* Based on uptime_proc_show(). */
1014 struct timespec64 uptime;
1016 if (setjmp(bus_error_jmp) == 0) {
1017 catch_memory_errors = 1;
1020 ktime_get_coarse_boottime_ts64(&uptime);
1021 printf("Uptime: %lu.%.2lu seconds\n", (unsigned long)uptime.tv_sec,
1022 ((unsigned long)uptime.tv_nsec / (NSEC_PER_SEC/100)));
1027 catch_memory_errors = 0;
1030 static void set_lpp_cmd(void)
1034 if (!scanhex(&lpp)) {
1035 printf("Invalid number.\n");
1038 xmon_set_pagination_lpp(lpp);
1040 /* Command interpreting routine */
1041 static char *last_cmd;
1044 cmds(struct pt_regs *excp)
1051 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1055 printf("%x:", smp_processor_id());
1056 #endif /* CONFIG_SMP */
1062 if (last_cmd == NULL)
1064 take_input(last_cmd);
1082 printf(xmon_ro_msg);
1102 prregs(excp); /* print regs */
1117 if (do_spu_cmd() == 0)
1124 if (tracing_enabled)
1128 printf(" <no input ...>\n");
1132 xmon_puts(help_string);
1152 printf(xmon_ro_msg);
1160 #if defined(CONFIG_PPC_BOOK3S_32) || defined(CONFIG_PPC_64S_HASH_MMU)
1164 #elif defined(CONFIG_44x)
1168 #elif defined(CONFIG_PPC_BOOK3E_64)
1177 printf("Unrecognized command: ");
1179 if (' ' < cmd && cmd <= '~')
1182 printf("\\x%x", cmd);
1184 } while (cmd != '\n');
1185 printf(" (type ? for help)\n");
1192 static int do_step(struct pt_regs *regs)
1194 regs_set_return_msr(regs, regs->msr | MSR_DE);
1195 mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
1200 * Step a single instruction.
1201 * Some instructions we emulate, others we execute with MSR_SE set.
1203 static int do_step(struct pt_regs *regs)
1208 force_enable_xmon();
1209 /* check we are in 64-bit kernel mode, translation enabled */
1210 if ((regs->msr & (MSR_64BIT|MSR_PR|MSR_IR)) == (MSR_64BIT|MSR_IR)) {
1211 if (mread_instr(regs->nip, &instr)) {
1212 stepped = emulate_step(regs, instr);
1214 printf("Couldn't single-step %s instruction\n",
1215 (IS_RFID(instr)? "rfid": "mtmsrd"));
1219 set_trap(regs, 0xd00);
1220 printf("stepped to ");
1221 xmon_print_symbol(regs->nip, " ", "\n");
1222 ppc_inst_dump(regs->nip, 1, 0);
1227 regs_set_return_msr(regs, regs->msr | MSR_SE);
1232 static void bootcmds(void)
1240 ppc_md.restart(tmp);
1241 } else if (cmd == 'h') {
1243 } else if (cmd == 'p') {
1244 do_kernel_power_off();
1249 static int xmon_switch_cpu(unsigned long cpu)
1257 while (!xmon_taken) {
1258 if (--timeout == 0) {
1259 if (test_and_set_bit(0, &xmon_taken))
1261 /* take control back */
1263 xmon_owner = smp_processor_id();
1264 printf("cpu 0x%lx didn't take control\n", cpu);
1272 static int xmon_batch_next_cpu(void)
1276 while (!cpumask_empty(&xmon_batch_cpus)) {
1277 cpu = cpumask_next_wrap(smp_processor_id(), &xmon_batch_cpus,
1278 xmon_batch_start_cpu, true);
1279 if (cpu >= nr_cpu_ids)
1281 if (xmon_batch_start_cpu == -1)
1282 xmon_batch_start_cpu = cpu;
1283 if (xmon_switch_cpu(cpu))
1285 cpumask_clear_cpu(cpu, &xmon_batch_cpus);
1289 printf("%x:mon> \n", smp_processor_id());
1293 static int batch_cmds(struct pt_regs *excp)
1297 /* simulate command entry */
1304 printf("%x:", smp_processor_id());
1306 printf("%c\n", (char)cmd);
1310 prregs(excp); /* print regs */
1320 cpumask_clear_cpu(smp_processor_id(), &xmon_batch_cpus);
1322 return xmon_batch_next_cpu();
1325 static int cpu_cmd(void)
1327 unsigned long cpu, first_cpu, last_cpu;
1331 xmon_batch = skipbl();
1333 switch (xmon_batch) {
1337 cpumask_copy(&xmon_batch_cpus, &cpus_in_xmon);
1338 if (cpumask_weight(&xmon_batch_cpus) <= 1) {
1339 printf("There are no other cpus in xmon\n");
1342 xmon_batch_start_cpu = -1;
1343 if (!xmon_batch_next_cpu())
1347 printf("c# only supports 'r', 'S' and 't' commands\n");
1355 if (!scanhex(&cpu)) {
1356 /* print cpus waiting or in xmon */
1357 printf("cpus stopped:");
1358 last_cpu = first_cpu = NR_CPUS;
1359 for_each_possible_cpu(cpu) {
1360 if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
1361 if (cpu == last_cpu + 1) {
1364 if (last_cpu != first_cpu)
1365 printf("-0x%lx", last_cpu);
1366 last_cpu = first_cpu = cpu;
1367 printf(" 0x%lx", cpu);
1371 if (last_cpu != first_cpu)
1372 printf("-0x%lx", last_cpu);
1376 /* try to switch to cpu specified */
1377 if (!cpumask_test_cpu(cpu, &cpus_in_xmon)) {
1378 printf("cpu 0x%lx isn't in xmon\n", cpu);
1380 printf("backtrace of paca[0x%lx].saved_r1 (possibly stale):\n", cpu);
1381 xmon_show_stack(paca_ptrs[cpu]->saved_r1, 0, 0);
1386 return xmon_switch_cpu(cpu);
1389 static int cpu_cmd(void)
1393 #endif /* CONFIG_SMP */
1395 static unsigned short fcstab[256] = {
1396 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
1397 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
1398 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
1399 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1400 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1401 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1402 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1403 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1404 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1405 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1406 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1407 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1408 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1409 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1410 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1411 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1412 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1413 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1414 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1415 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1416 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1417 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1418 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1419 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1420 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1421 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1422 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1423 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1424 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1425 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1426 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1427 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1430 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1439 if (!scanhex(&adrs))
1441 if (!scanhex(&ncsum))
1444 for (i = 0; i < ncsum; ++i) {
1445 if (mread(adrs+i, &v, 1) == 0) {
1446 printf("csum stopped at "REG"\n", adrs+i);
1451 printf("%x\n", fcs);
1455 * Check if this is a suitable place to put a breakpoint.
1457 static long check_bp_loc(unsigned long addr)
1462 if (!is_kernel_addr(addr)) {
1463 printf("Breakpoints may only be placed at kernel addresses\n");
1466 if (!mread_instr(addr, &instr)) {
1467 printf("Can't read instruction at address %lx\n", addr);
1470 if (!can_single_step(ppc_inst_val(instr))) {
1471 printf("Breakpoints may not be placed on instructions that can't be single stepped\n");
1477 static int find_free_data_bpt(void)
1481 for (i = 0; i < nr_wp_slots(); i++) {
1482 if (!dabr[i].enabled)
1485 printf("Couldn't find free breakpoint register\n");
1489 static void print_data_bpts(void)
1493 for (i = 0; i < nr_wp_slots(); i++) {
1494 if (!dabr[i].enabled)
1497 printf(" data "REG" [", dabr[i].address);
1498 if (dabr[i].enabled & 1)
1500 if (dabr[i].enabled & 2)
1506 static char *breakpoint_help_string =
1507 "Breakpoint command usage:\n"
1508 "b show breakpoints\n"
1509 "b <addr> [cnt] set breakpoint at given instr addr\n"
1510 "bc clear all breakpoints\n"
1511 "bc <n/addr> clear breakpoint number n or at addr\n"
1512 "bi <addr> [cnt] set hardware instr breakpoint (POWER8 only)\n"
1513 "bd <addr> [cnt] set hardware data breakpoint\n"
1527 case 'd': { /* bd - hardware data breakpoint */
1528 static const char badaddr[] = "Only kernel addresses are permitted for breakpoints\n";
1531 printf(xmon_ro_msg);
1534 if (!ppc_breakpoint_available()) {
1535 printf("Hardware data breakpoint not supported on this cpu\n");
1538 i = find_free_data_bpt();
1545 else if (cmd == 'w')
1549 dabr[i].address = 0;
1550 dabr[i].enabled = 0;
1551 if (scanhex(&dabr[i].address)) {
1552 if (!is_kernel_addr(dabr[i].address)) {
1556 dabr[i].address &= ~HW_BRK_TYPE_DABR;
1557 dabr[i].enabled = mode | BP_DABR;
1560 force_enable_xmon();
1564 case 'i': /* bi - hardware instr breakpoint */
1566 printf(xmon_ro_msg);
1569 if (!cpu_has_feature(CPU_FTR_ARCH_207S)) {
1570 printf("Hardware instruction breakpoint "
1571 "not supported on this cpu\n");
1575 iabr->enabled &= ~BP_CIABR;
1580 if (!check_bp_loc(a))
1582 bp = new_breakpoint(a);
1584 bp->enabled |= BP_CIABR;
1586 force_enable_xmon();
1592 /* clear all breakpoints */
1593 for (i = 0; i < NBPTS; ++i)
1594 bpts[i].enabled = 0;
1596 for (i = 0; i < nr_wp_slots(); i++)
1597 dabr[i].enabled = 0;
1599 printf("All breakpoints cleared\n");
1603 if (a <= NBPTS && a >= 1) {
1604 /* assume a breakpoint number */
1605 bp = &bpts[a-1]; /* bp nums are 1 based */
1607 /* assume a breakpoint address */
1608 bp = at_breakpoint(a);
1610 printf("No breakpoint at %lx\n", a);
1615 printf("Cleared breakpoint %tx (", BP_NUM(bp));
1616 xmon_print_symbol(bp->address, " ", ")\n");
1624 printf(breakpoint_help_string);
1629 if (xmon_is_ro || !scanhex(&a)) {
1630 /* print all breakpoints */
1631 printf(" type address\n");
1633 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1636 printf("%tx %s ", BP_NUM(bp),
1637 (bp->enabled & BP_CIABR) ? "inst": "trap");
1638 xmon_print_symbol(bp->address, " ", "\n");
1643 if (!check_bp_loc(a))
1645 bp = new_breakpoint(a);
1647 bp->enabled |= BP_TRAP;
1648 force_enable_xmon();
1654 /* Very cheap human name for vector lookup. */
1656 const char *getvecname(unsigned long vec)
1661 case 0x100: ret = "(System Reset)"; break;
1662 case 0x200: ret = "(Machine Check)"; break;
1663 case 0x300: ret = "(Data Access)"; break;
1665 if (radix_enabled())
1666 ret = "(Data Access Out of Range)";
1668 ret = "(Data SLB Access)";
1670 case 0x400: ret = "(Instruction Access)"; break;
1672 if (radix_enabled())
1673 ret = "(Instruction Access Out of Range)";
1675 ret = "(Instruction SLB Access)";
1677 case 0x500: ret = "(Hardware Interrupt)"; break;
1678 case 0x600: ret = "(Alignment)"; break;
1679 case 0x700: ret = "(Program Check)"; break;
1680 case 0x800: ret = "(FPU Unavailable)"; break;
1681 case 0x900: ret = "(Decrementer)"; break;
1682 case 0x980: ret = "(Hypervisor Decrementer)"; break;
1683 case 0xa00: ret = "(Doorbell)"; break;
1684 case 0xc00: ret = "(System Call)"; break;
1685 case 0xd00: ret = "(Single Step)"; break;
1686 case 0xe40: ret = "(Emulation Assist)"; break;
1687 case 0xe60: ret = "(HMI)"; break;
1688 case 0xe80: ret = "(Hypervisor Doorbell)"; break;
1689 case 0xf00: ret = "(Performance Monitor)"; break;
1690 case 0xf20: ret = "(Altivec Unavailable)"; break;
1691 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1692 case 0x1500: ret = "(Denormalisation)"; break;
1693 case 0x1700: ret = "(Altivec Assist)"; break;
1694 case 0x3000: ret = "(System Call Vectored)"; break;
1700 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1701 unsigned long *endp)
1703 unsigned long size, offset;
1706 *startp = *endp = 0;
1709 if (setjmp(bus_error_jmp) == 0) {
1710 catch_memory_errors = 1;
1712 name = kallsyms_lookup(pc, &size, &offset, NULL, tmpstr);
1714 *startp = pc - offset;
1715 *endp = pc - offset + size;
1719 catch_memory_errors = 0;
1722 #define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1724 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1727 int max_to_print = 64;
1729 unsigned long newsp;
1730 unsigned long marker;
1731 struct pt_regs regs;
1733 while (max_to_print--) {
1734 if (!is_kernel_addr(sp)) {
1736 printf("SP (%lx) is in userspace\n", sp);
1740 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1741 || !mread(sp, &newsp, sizeof(unsigned long))) {
1742 printf("Couldn't read stack frame at %lx\n", sp);
1747 * For the first stack frame, try to work out if
1748 * LR and/or the saved LR value in the bottommost
1749 * stack frame are valid.
1751 if ((pc | lr) != 0) {
1752 unsigned long fnstart, fnend;
1753 unsigned long nextip;
1756 get_function_bounds(pc, &fnstart, &fnend);
1759 mread(newsp + LRSAVE_OFFSET, &nextip,
1760 sizeof(unsigned long));
1762 if (!is_kernel_addr(lr)
1763 || (fnstart <= lr && lr < fnend))
1765 } else if (lr == nextip) {
1767 } else if (is_kernel_addr(lr)
1768 && !(fnstart <= lr && lr < fnend)) {
1769 printf("[link register ] ");
1770 xmon_print_symbol(lr, " ", "\n");
1773 printf("["REG"] ", sp);
1774 xmon_print_symbol(ip, " ", " (unreliable)\n");
1779 printf("["REG"] ", sp);
1780 xmon_print_symbol(ip, " ", "\n");
1783 /* Look for "regs" marker to see if this is
1784 an exception frame. */
1785 if (mread(sp + STACK_INT_FRAME_MARKER, &marker, sizeof(unsigned long))
1786 && marker == STACK_FRAME_REGS_MARKER) {
1787 if (mread(sp + STACK_INT_FRAME_REGS, ®s, sizeof(regs)) != sizeof(regs)) {
1788 printf("Couldn't read registers at %lx\n",
1789 sp + STACK_INT_FRAME_REGS);
1792 printf("--- Exception: %lx %s at ", regs.trap,
1793 getvecname(TRAP(®s)));
1796 xmon_print_symbol(pc, " ", "\n");
1806 static void backtrace(struct pt_regs *excp)
1811 xmon_show_stack(sp, 0, 0);
1813 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1817 static void print_bug_trap(struct pt_regs *regs)
1820 const struct bug_entry *bug;
1823 if (regs->msr & MSR_PR)
1824 return; /* not in kernel */
1825 addr = regs->nip; /* address of trap instruction */
1826 if (!is_kernel_addr(addr))
1828 bug = find_bug(regs->nip);
1831 if (is_warning_bug(bug))
1834 #ifdef CONFIG_DEBUG_BUGVERBOSE
1835 printf("kernel BUG at %s:%u!\n",
1836 (char *)bug + bug->file_disp, bug->line);
1838 printf("kernel BUG at %px!\n", (void *)bug + bug->bug_addr_disp);
1840 #endif /* CONFIG_BUG */
1843 static void excprint(struct pt_regs *fp)
1848 printf("cpu 0x%x: ", smp_processor_id());
1849 #endif /* CONFIG_SMP */
1852 printf("Vector: %lx %s at [%px]\n", fp->trap, getvecname(trap), fp);
1854 xmon_print_symbol(fp->nip, ": ", "\n");
1857 xmon_print_symbol(fp->link, ": ", "\n");
1859 printf(" sp: %lx\n", fp->gpr[1]);
1860 printf(" msr: %lx\n", fp->msr);
1862 if (trap == INTERRUPT_DATA_STORAGE ||
1863 trap == INTERRUPT_DATA_SEGMENT ||
1864 trap == INTERRUPT_ALIGNMENT ||
1865 trap == INTERRUPT_MACHINE_CHECK) {
1866 printf(" dar: %lx\n", fp->dar);
1867 if (trap != INTERRUPT_DATA_SEGMENT)
1868 printf(" dsisr: %lx\n", fp->dsisr);
1871 printf(" current = 0x%px\n", current);
1873 printf(" paca = 0x%px\t irqmask: 0x%02x\t irq_happened: 0x%02x\n",
1874 local_paca, local_paca->irq_soft_mask, local_paca->irq_happened);
1877 printf(" pid = %d, comm = %s\n",
1878 current->pid, current->comm);
1881 if (trap == INTERRUPT_PROGRAM)
1884 printf(linux_banner);
1887 static void prregs(struct pt_regs *fp)
1891 struct pt_regs regs;
1893 if (scanhex(&base)) {
1894 if (setjmp(bus_error_jmp) == 0) {
1895 catch_memory_errors = 1;
1897 regs = *(struct pt_regs *)base;
1901 catch_memory_errors = 0;
1902 printf("*** Error reading registers from "REG"\n",
1906 catch_memory_errors = 0;
1911 #define R_PER_LINE 2
1913 #define R_PER_LINE 4
1916 for (n = 0; n < 32; ++n) {
1917 printf("R%.2d = "REG"%s", n, fp->gpr[n],
1918 (n % R_PER_LINE) == R_PER_LINE - 1 ? "\n" : " ");
1922 xmon_print_symbol(fp->nip, " ", "\n");
1923 if (!trap_is_syscall(fp) && cpu_has_feature(CPU_FTR_CFAR)) {
1925 xmon_print_symbol(fp->orig_gpr3, " ", "\n");
1928 xmon_print_symbol(fp->link, " ", "\n");
1929 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
1930 printf("ctr = "REG" xer = "REG" trap = %4lx\n",
1931 fp->ctr, fp->xer, fp->trap);
1933 if (trap == INTERRUPT_DATA_STORAGE ||
1934 trap == INTERRUPT_DATA_SEGMENT ||
1935 trap == INTERRUPT_ALIGNMENT)
1936 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1939 static void cacheflush(void)
1942 unsigned long nflush;
1947 scanhex((void *)&adrs);
1952 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1953 if (setjmp(bus_error_jmp) == 0) {
1954 catch_memory_errors = 1;
1957 if (cmd != 'i' || IS_ENABLED(CONFIG_PPC_BOOK3S_64)) {
1958 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1959 cflush((void *) adrs);
1961 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1962 cinval((void *) adrs);
1965 /* wait a little while to see if we get a machine check */
1968 catch_memory_errors = 0;
1971 extern unsigned long xmon_mfspr(int spr, unsigned long default_value);
1972 extern void xmon_mtspr(int spr, unsigned long value);
1975 read_spr(int n, unsigned long *vp)
1977 unsigned long ret = -1UL;
1980 if (setjmp(bus_error_jmp) == 0) {
1981 catch_spr_faults = 1;
1984 ret = xmon_mfspr(n, *vp);
1990 catch_spr_faults = 0;
1996 write_spr(int n, unsigned long val)
1999 printf(xmon_ro_msg);
2003 if (setjmp(bus_error_jmp) == 0) {
2004 catch_spr_faults = 1;
2011 printf("SPR 0x%03x (%4d) Faulted during write\n", n, n);
2013 catch_spr_faults = 0;
2016 static void dump_206_sprs(void)
2019 if (!cpu_has_feature(CPU_FTR_ARCH_206))
2022 /* Actually some of these pre-date 2.06, but whatever */
2024 printf("srr0 = %.16lx srr1 = %.16lx dsisr = %.8lx\n",
2025 mfspr(SPRN_SRR0), mfspr(SPRN_SRR1), mfspr(SPRN_DSISR));
2026 printf("dscr = %.16lx ppr = %.16lx pir = %.8lx\n",
2027 mfspr(SPRN_DSCR), mfspr(SPRN_PPR), mfspr(SPRN_PIR));
2028 printf("amr = %.16lx uamor = %.16lx\n",
2029 mfspr(SPRN_AMR), mfspr(SPRN_UAMOR));
2031 if (!(mfmsr() & MSR_HV))
2034 printf("sdr1 = %.16lx hdar = %.16lx hdsisr = %.8lx\n",
2035 mfspr(SPRN_SDR1), mfspr(SPRN_HDAR), mfspr(SPRN_HDSISR));
2036 printf("hsrr0 = %.16lx hsrr1 = %.16lx hdec = %.16lx\n",
2037 mfspr(SPRN_HSRR0), mfspr(SPRN_HSRR1), mfspr(SPRN_HDEC));
2038 printf("lpcr = %.16lx pcr = %.16lx lpidr = %.8lx\n",
2039 mfspr(SPRN_LPCR), mfspr(SPRN_PCR), mfspr(SPRN_LPID));
2040 printf("hsprg0 = %.16lx hsprg1 = %.16lx amor = %.16lx\n",
2041 mfspr(SPRN_HSPRG0), mfspr(SPRN_HSPRG1), mfspr(SPRN_AMOR));
2042 printf("dabr = %.16lx dabrx = %.16lx\n",
2043 mfspr(SPRN_DABR), mfspr(SPRN_DABRX));
2047 static void dump_207_sprs(void)
2052 if (!cpu_has_feature(CPU_FTR_ARCH_207S))
2055 printf("dpdes = %.16lx tir = %.16lx cir = %.8lx\n",
2056 mfspr(SPRN_DPDES), mfspr(SPRN_TIR), mfspr(SPRN_CIR));
2058 printf("fscr = %.16lx tar = %.16lx pspb = %.8lx\n",
2059 mfspr(SPRN_FSCR), mfspr(SPRN_TAR), mfspr(SPRN_PSPB));
2063 /* Only if TM has been enabled in the kernel */
2064 printf("tfhar = %.16lx tfiar = %.16lx texasr = %.16lx\n",
2065 mfspr(SPRN_TFHAR), mfspr(SPRN_TFIAR),
2066 mfspr(SPRN_TEXASR));
2069 printf("mmcr0 = %.16lx mmcr1 = %.16lx mmcr2 = %.16lx\n",
2070 mfspr(SPRN_MMCR0), mfspr(SPRN_MMCR1), mfspr(SPRN_MMCR2));
2071 printf("pmc1 = %.8lx pmc2 = %.8lx pmc3 = %.8lx pmc4 = %.8lx\n",
2072 mfspr(SPRN_PMC1), mfspr(SPRN_PMC2),
2073 mfspr(SPRN_PMC3), mfspr(SPRN_PMC4));
2074 printf("mmcra = %.16lx siar = %.16lx pmc5 = %.8lx\n",
2075 mfspr(SPRN_MMCRA), mfspr(SPRN_SIAR), mfspr(SPRN_PMC5));
2076 printf("sdar = %.16lx sier = %.16lx pmc6 = %.8lx\n",
2077 mfspr(SPRN_SDAR), mfspr(SPRN_SIER), mfspr(SPRN_PMC6));
2078 printf("ebbhr = %.16lx ebbrr = %.16lx bescr = %.16lx\n",
2079 mfspr(SPRN_EBBHR), mfspr(SPRN_EBBRR), mfspr(SPRN_BESCR));
2080 printf("iamr = %.16lx\n", mfspr(SPRN_IAMR));
2082 if (!(msr & MSR_HV))
2085 printf("hfscr = %.16lx dhdes = %.16lx rpr = %.16lx\n",
2086 mfspr(SPRN_HFSCR), mfspr(SPRN_DHDES), mfspr(SPRN_RPR));
2087 printf("dawr0 = %.16lx dawrx0 = %.16lx\n",
2088 mfspr(SPRN_DAWR0), mfspr(SPRN_DAWRX0));
2089 if (nr_wp_slots() > 1) {
2090 printf("dawr1 = %.16lx dawrx1 = %.16lx\n",
2091 mfspr(SPRN_DAWR1), mfspr(SPRN_DAWRX1));
2093 printf("ciabr = %.16lx\n", mfspr(SPRN_CIABR));
2097 static void dump_300_sprs(void)
2100 bool hv = mfmsr() & MSR_HV;
2102 if (!cpu_has_feature(CPU_FTR_ARCH_300))
2105 if (cpu_has_feature(CPU_FTR_P9_TIDR)) {
2106 printf("pidr = %.16lx tidr = %.16lx\n",
2107 mfspr(SPRN_PID), mfspr(SPRN_TIDR));
2109 printf("pidr = %.16lx\n",
2113 printf("psscr = %.16lx\n",
2114 hv ? mfspr(SPRN_PSSCR) : mfspr(SPRN_PSSCR_PR));
2119 printf("ptcr = %.16lx asdr = %.16lx\n",
2120 mfspr(SPRN_PTCR), mfspr(SPRN_ASDR));
2124 static void dump_310_sprs(void)
2127 if (!cpu_has_feature(CPU_FTR_ARCH_31))
2130 printf("mmcr3 = %.16lx, sier2 = %.16lx, sier3 = %.16lx\n",
2131 mfspr(SPRN_MMCR3), mfspr(SPRN_SIER2), mfspr(SPRN_SIER3));
2136 static void dump_one_spr(int spr, bool show_unimplemented)
2141 if (!read_spr(spr, &val)) {
2142 printf("SPR 0x%03x (%4d) Faulted during read\n", spr, spr);
2146 if (val == 0xdeadbeef) {
2147 /* Looks like read was a nop, confirm */
2149 if (!read_spr(spr, &val)) {
2150 printf("SPR 0x%03x (%4d) Faulted during read\n", spr, spr);
2154 if (val == 0x0badcafe) {
2155 if (show_unimplemented)
2156 printf("SPR 0x%03x (%4d) Unimplemented\n", spr, spr);
2161 printf("SPR 0x%03x (%4d) = 0x%lx\n", spr, spr, val);
2164 static void super_regs(void)
2166 static unsigned long regno;
2174 unsigned long sp, toc;
2175 asm("mr %0,1" : "=r" (sp) :);
2176 asm("mr %0,2" : "=r" (toc) :);
2178 printf("msr = "REG" sprg0 = "REG"\n",
2179 mfmsr(), mfspr(SPRN_SPRG0));
2180 printf("pvr = "REG" sprg1 = "REG"\n",
2181 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
2182 printf("dec = "REG" sprg2 = "REG"\n",
2183 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
2184 printf("sp = "REG" sprg3 = "REG"\n", sp, mfspr(SPRN_SPRG3));
2185 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
2198 read_spr(regno, &val);
2200 write_spr(regno, val);
2201 dump_one_spr(regno, true);
2206 dump_one_spr(regno, true);
2210 for (spr = 1; spr < 1024; ++spr)
2211 dump_one_spr(spr, false);
2219 * Stuff for reading and writing memory safely
2222 mread(unsigned long adrs, void *buf, int size)
2228 if (setjmp(bus_error_jmp) == 0) {
2229 catch_memory_errors = 1;
2235 *(u16 *)q = *(u16 *)p;
2238 *(u32 *)q = *(u32 *)p;
2241 *(u64 *)q = *(u64 *)p;
2244 for( ; n < size; ++n) {
2250 /* wait a little while to see if we get a machine check */
2254 catch_memory_errors = 0;
2259 mwrite(unsigned long adrs, void *buf, int size)
2267 printf(xmon_ro_msg);
2271 if (setjmp(bus_error_jmp) == 0) {
2272 catch_memory_errors = 1;
2278 *(u16 *)p = *(u16 *)q;
2281 *(u32 *)p = *(u32 *)q;
2284 *(u64 *)p = *(u64 *)q;
2287 for ( ; n < size; ++n) {
2293 /* wait a little while to see if we get a machine check */
2297 printf("*** Error writing address "REG"\n", adrs + n);
2299 catch_memory_errors = 0;
2304 mread_instr(unsigned long adrs, ppc_inst_t *instr)
2309 if (setjmp(bus_error_jmp) == 0) {
2310 catch_memory_errors = 1;
2312 *instr = ppc_inst_read((u32 *)adrs);
2314 /* wait a little while to see if we get a machine check */
2316 n = ppc_inst_len(*instr);
2318 catch_memory_errors = 0;
2322 static int fault_type;
2323 static int fault_except;
2324 static char *fault_chars[] = { "--", "**", "##" };
2326 static int handle_fault(struct pt_regs *regs)
2328 fault_except = TRAP(regs);
2329 switch (TRAP(regs)) {
2341 longjmp(bus_error_jmp, 1);
2346 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
2349 byterev(unsigned char *val, int size)
2355 SWAP(val[0], val[1], t);
2358 SWAP(val[0], val[3], t);
2359 SWAP(val[1], val[2], t);
2361 case 8: /* is there really any use for this? */
2362 SWAP(val[0], val[7], t);
2363 SWAP(val[1], val[6], t);
2364 SWAP(val[2], val[5], t);
2365 SWAP(val[3], val[4], t);
2373 static char *memex_help_string =
2374 "Memory examine command usage:\n"
2375 "m [addr] [flags] examine/change memory\n"
2376 " addr is optional. will start where left off.\n"
2377 " flags may include chars from this set:\n"
2378 " b modify by bytes (default)\n"
2379 " w modify by words (2 byte)\n"
2380 " l modify by longs (4 byte)\n"
2381 " d modify by doubleword (8 byte)\n"
2382 " r toggle reverse byte order mode\n"
2383 " n do not read memory (for i/o spaces)\n"
2384 " . ok to read (default)\n"
2385 "NOTE: flags are saved as defaults\n"
2388 static char *memex_subcmd_help_string =
2389 "Memory examine subcommands:\n"
2390 " hexval write this val to current location\n"
2391 " 'string' write chars from string to this location\n"
2392 " ' increment address\n"
2393 " ^ decrement address\n"
2394 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
2395 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
2396 " ` clear no-read flag\n"
2397 " ; stay at this addr\n"
2398 " v change to byte mode\n"
2399 " w change to word (2 byte) mode\n"
2400 " l change to long (4 byte) mode\n"
2401 " u change to doubleword (8 byte) mode\n"
2402 " m addr change current addr\n"
2403 " n toggle no-read flag\n"
2404 " r toggle byte reverse flag\n"
2405 " < count back up count bytes\n"
2406 " > count skip forward count bytes\n"
2407 " x exit this mode\n"
2413 int cmd, inc, i, nslash;
2415 unsigned char val[16];
2417 scanhex((void *)&adrs);
2420 printf(memex_help_string);
2426 while ((cmd = skipbl()) != '\n') {
2428 case 'b': size = 1; break;
2429 case 'w': size = 2; break;
2430 case 'l': size = 4; break;
2431 case 'd': size = 8; break;
2432 case 'r': brev = !brev; break;
2433 case 'n': mnoread = 1; break;
2434 case '.': mnoread = 0; break;
2443 n = mread(adrs, val, size);
2444 printf(REG"%c", adrs, brev? 'r': ' ');
2449 for (i = 0; i < n; ++i)
2450 printf("%.2x", val[i]);
2451 for (; i < size; ++i)
2452 printf("%s", fault_chars[fault_type]);
2459 for (i = 0; i < size; ++i)
2460 val[i] = n >> (i * 8);
2463 mwrite(adrs, val, size);
2476 else if( n == '\'' )
2478 for (i = 0; i < size; ++i)
2479 val[i] = n >> (i * 8);
2482 mwrite(adrs, val, size);
2518 adrs -= 1 << nslash;
2522 adrs += 1 << nslash;
2526 adrs += 1 << -nslash;
2530 adrs -= 1 << -nslash;
2533 scanhex((void *)&adrs);
2552 printf(memex_subcmd_help_string);
2567 case 'n': c = '\n'; break;
2568 case 'r': c = '\r'; break;
2569 case 'b': c = '\b'; break;
2570 case 't': c = '\t'; break;
2575 static void xmon_rawdump (unsigned long adrs, long ndump)
2578 unsigned char temp[16];
2580 for (n = ndump; n > 0;) {
2582 nr = mread(adrs, temp, r);
2584 for (m = 0; m < r; ++m) {
2586 printf("%.2x", temp[m]);
2588 printf("%s", fault_chars[fault_type]);
2597 static void dump_tracing(void)
2603 ftrace_dump(DUMP_ORIG);
2605 ftrace_dump(DUMP_ALL);
2609 static void dump_one_paca(int cpu)
2611 struct paca_struct *p;
2612 #ifdef CONFIG_PPC_64S_HASH_MMU
2616 if (setjmp(bus_error_jmp) != 0) {
2617 printf("*** Error dumping paca for cpu 0x%x!\n", cpu);
2621 catch_memory_errors = 1;
2626 printf("paca for cpu 0x%x @ %px:\n", cpu, p);
2628 printf(" %-*s = %s\n", 25, "possible", cpu_possible(cpu) ? "yes" : "no");
2629 printf(" %-*s = %s\n", 25, "present", cpu_present(cpu) ? "yes" : "no");
2630 printf(" %-*s = %s\n", 25, "online", cpu_online(cpu) ? "yes" : "no");
2632 #define DUMP(paca, name, format) \
2633 printf(" %-*s = "format"\t(0x%lx)\n", 25, #name, 18, paca->name, \
2634 offsetof(struct paca_struct, name));
2636 DUMP(p, lock_token, "%#-*x");
2637 DUMP(p, paca_index, "%#-*x");
2638 #ifndef CONFIG_PPC_KERNEL_PCREL
2639 DUMP(p, kernel_toc, "%#-*llx");
2641 DUMP(p, kernelbase, "%#-*llx");
2642 DUMP(p, kernel_msr, "%#-*llx");
2643 DUMP(p, emergency_sp, "%-*px");
2644 #ifdef CONFIG_PPC_BOOK3S_64
2645 DUMP(p, nmi_emergency_sp, "%-*px");
2646 DUMP(p, mc_emergency_sp, "%-*px");
2647 DUMP(p, in_nmi, "%#-*x");
2648 DUMP(p, in_mce, "%#-*x");
2649 DUMP(p, hmi_event_available, "%#-*x");
2651 DUMP(p, data_offset, "%#-*llx");
2652 DUMP(p, hw_cpu_id, "%#-*x");
2653 DUMP(p, cpu_start, "%#-*x");
2654 DUMP(p, kexec_state, "%#-*x");
2655 #ifdef CONFIG_PPC_BOOK3S_64
2656 #ifdef CONFIG_PPC_64S_HASH_MMU
2657 if (!early_radix_enabled()) {
2658 for (i = 0; i < SLB_NUM_BOLTED; i++) {
2661 if (!p->slb_shadow_ptr)
2664 esid = be64_to_cpu(p->slb_shadow_ptr->save_area[i].esid);
2665 vsid = be64_to_cpu(p->slb_shadow_ptr->save_area[i].vsid);
2668 printf(" %-*s[%d] = 0x%016llx 0x%016llx\n",
2669 22, "slb_shadow", i, esid, vsid);
2672 DUMP(p, vmalloc_sllp, "%#-*x");
2673 DUMP(p, stab_rr, "%#-*x");
2674 DUMP(p, slb_used_bitmap, "%#-*x");
2675 DUMP(p, slb_kern_bitmap, "%#-*x");
2677 if (!early_cpu_has_feature(CPU_FTR_ARCH_300)) {
2678 DUMP(p, slb_cache_ptr, "%#-*x");
2679 for (i = 0; i < SLB_CACHE_ENTRIES; i++)
2680 printf(" %-*s[%d] = 0x%016x\n",
2681 22, "slb_cache", i, p->slb_cache[i]);
2686 DUMP(p, rfi_flush_fallback_area, "%-*px");
2688 DUMP(p, dscr_default, "%#-*llx");
2689 #ifdef CONFIG_PPC_BOOK3E_64
2690 DUMP(p, pgd, "%-*px");
2691 DUMP(p, kernel_pgd, "%-*px");
2692 DUMP(p, tcd_ptr, "%-*px");
2693 DUMP(p, mc_kstack, "%-*px");
2694 DUMP(p, crit_kstack, "%-*px");
2695 DUMP(p, dbg_kstack, "%-*px");
2697 DUMP(p, __current, "%-*px");
2698 DUMP(p, kstack, "%#-*llx");
2699 printf(" %-*s = 0x%016llx\n", 25, "kstack_base", p->kstack & ~(THREAD_SIZE - 1));
2700 #ifdef CONFIG_STACKPROTECTOR
2701 DUMP(p, canary, "%#-*lx");
2703 DUMP(p, saved_r1, "%#-*llx");
2704 #ifdef CONFIG_PPC_BOOK3E_64
2705 DUMP(p, trap_save, "%#-*x");
2707 DUMP(p, irq_soft_mask, "%#-*x");
2708 DUMP(p, irq_happened, "%#-*x");
2709 #ifdef CONFIG_MMIOWB
2710 DUMP(p, mmiowb_state.nesting_count, "%#-*x");
2711 DUMP(p, mmiowb_state.mmiowb_pending, "%#-*x");
2713 DUMP(p, irq_work_pending, "%#-*x");
2714 DUMP(p, sprg_vdso, "%#-*llx");
2716 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
2717 DUMP(p, tm_scratch, "%#-*llx");
2720 #ifdef CONFIG_PPC_POWERNV
2721 DUMP(p, idle_state, "%#-*lx");
2722 if (!early_cpu_has_feature(CPU_FTR_ARCH_300)) {
2723 DUMP(p, thread_idle_state, "%#-*x");
2724 DUMP(p, subcore_sibling_mask, "%#-*x");
2726 #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
2727 DUMP(p, requested_psscr, "%#-*llx");
2728 DUMP(p, dont_stop.counter, "%#-*x");
2733 DUMP(p, accounting.utime, "%#-*lx");
2734 DUMP(p, accounting.stime, "%#-*lx");
2735 #ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
2736 DUMP(p, accounting.utime_scaled, "%#-*lx");
2738 DUMP(p, accounting.starttime, "%#-*lx");
2739 DUMP(p, accounting.starttime_user, "%#-*lx");
2740 #ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
2741 DUMP(p, accounting.startspurr, "%#-*lx");
2742 DUMP(p, accounting.utime_sspurr, "%#-*lx");
2744 DUMP(p, accounting.steal_time, "%#-*lx");
2747 catch_memory_errors = 0;
2751 static void dump_all_pacas(void)
2755 if (num_possible_cpus() == 0) {
2756 printf("No possible cpus, use 'dp #' to dump individual cpus\n");
2760 for_each_possible_cpu(cpu)
2764 static void dump_pacas(void)
2775 termch = c; /* Put c back, it wasn't 'a' */
2780 dump_one_paca(xmon_owner);
2784 #ifdef CONFIG_PPC_POWERNV
2785 static void dump_one_xive(int cpu)
2787 unsigned int hwid = get_hard_smp_processor_id(cpu);
2788 bool hv = cpu_has_feature(CPU_FTR_HVMODE);
2791 opal_xive_dump(XIVE_DUMP_TM_HYP, hwid);
2792 opal_xive_dump(XIVE_DUMP_TM_POOL, hwid);
2793 opal_xive_dump(XIVE_DUMP_TM_OS, hwid);
2794 opal_xive_dump(XIVE_DUMP_TM_USER, hwid);
2795 opal_xive_dump(XIVE_DUMP_VP, hwid);
2796 opal_xive_dump(XIVE_DUMP_EMU_STATE, hwid);
2799 if (setjmp(bus_error_jmp) != 0) {
2800 catch_memory_errors = 0;
2801 printf("*** Error dumping xive on cpu %d\n", cpu);
2805 catch_memory_errors = 1;
2807 xmon_xive_do_dump(cpu);
2810 catch_memory_errors = 0;
2813 static void dump_all_xives(void)
2817 if (num_online_cpus() == 0) {
2818 printf("No possible cpus, use 'dx #' to dump individual cpus\n");
2822 for_each_online_cpu(cpu)
2826 static void dump_xives(void)
2831 if (!xive_enabled()) {
2832 printf("Xive disabled on this system\n");
2840 } else if (c == 'i') {
2842 xmon_xive_get_irq_config(num, NULL);
2844 xmon_xive_get_irq_all();
2848 termch = c; /* Put c back, it wasn't 'a' */
2853 dump_one_xive(xmon_owner);
2855 #endif /* CONFIG_PPC_POWERNV */
2857 static void dump_by_size(unsigned long addr, long count, int size)
2859 unsigned char temp[16];
2863 count = ALIGN(count, 16);
2865 for (i = 0; i < count; i += 16, addr += 16) {
2868 if (mread(addr, temp, 16) != 16) {
2869 printf("\nFaulted reading %d bytes from 0x"REG"\n", 16, addr);
2873 for (j = 0; j < 16; j += size) {
2876 case 1: val = temp[j]; break;
2877 case 2: val = *(u16 *)&temp[j]; break;
2878 case 4: val = *(u32 *)&temp[j]; break;
2879 case 8: val = *(u64 *)&temp[j]; break;
2883 printf("%0*llx", size * 2, val);
2886 for (j = 0; j < 16; ++j) {
2888 putchar(' ' <= val && val <= '~' ? val : '.');
2897 static char last[] = { "d?\n" };
2904 xmon_start_pagination();
2906 xmon_end_pagination();
2910 #ifdef CONFIG_PPC_POWERNV
2912 xmon_start_pagination();
2914 xmon_end_pagination();
2927 scanhex((void *)&adrs);
2934 else if (nidump > MAX_IDUMP)
2936 adrs += ppc_inst_dump(adrs, nidump, 1);
2938 } else if (c == 'l') {
2940 } else if (c == 'o') {
2942 } else if (c == 'v') {
2943 /* dump virtual to physical translation */
2945 } else if (c == 'r') {
2949 xmon_rawdump(adrs, ndump);
2956 else if (ndump > MAX_DUMP)
2964 ndump = ALIGN(ndump, 16);
2965 dump_by_size(adrs, ndump, c - '0');
2970 prdump(adrs, ndump);
2979 prdump(unsigned long adrs, long ndump)
2981 long n, m, c, r, nr;
2982 unsigned char temp[16];
2984 for (n = ndump; n > 0;) {
2988 nr = mread(adrs, temp, r);
2990 for (m = 0; m < r; ++m) {
2991 if ((m & (sizeof(long) - 1)) == 0 && m > 0)
2994 printf("%.2x", temp[m]);
2996 printf("%s", fault_chars[fault_type]);
2998 for (; m < 16; ++m) {
2999 if ((m & (sizeof(long) - 1)) == 0)
3004 for (m = 0; m < r; ++m) {
3007 putchar(' ' <= c && c <= '~'? c: '.');
3020 typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr);
3023 generic_inst_dump(unsigned long adr, long count, int praddr,
3024 instruction_dump_func dump_func)
3027 unsigned long first_adr;
3028 ppc_inst_t inst, last_inst = ppc_inst(0);
3031 for (first_adr = adr; count > 0; --count, adr += ppc_inst_len(inst)) {
3032 nr = mread_instr(adr, &inst);
3035 const char *x = fault_chars[fault_type];
3036 printf(REG" %s%s%s%s\n", adr, x, x, x, x);
3040 if (adr > first_adr && ppc_inst_equal(inst, last_inst)) {
3050 printf(REG" %08lx", adr, ppc_inst_as_ulong(inst));
3052 if (!ppc_inst_prefixed(inst))
3053 dump_func(ppc_inst_val(inst), adr);
3055 dump_func(ppc_inst_as_ulong(inst), adr);
3058 return adr - first_adr;
3062 ppc_inst_dump(unsigned long adr, long count, int praddr)
3064 return generic_inst_dump(adr, count, praddr, print_insn_powerpc);
3068 print_address(unsigned long addr)
3070 xmon_print_symbol(addr, "\t# ", "");
3076 struct kmsg_dump_iter iter;
3077 static unsigned char buf[1024];
3080 if (setjmp(bus_error_jmp) != 0) {
3081 printf("Error dumping printk buffer!\n");
3085 catch_memory_errors = 1;
3088 kmsg_dump_rewind(&iter);
3089 xmon_start_pagination();
3090 while (kmsg_dump_get_line(&iter, false, buf, sizeof(buf), &len)) {
3094 xmon_end_pagination();
3097 /* wait a little while to see if we get a machine check */
3099 catch_memory_errors = 0;
3102 #ifdef CONFIG_PPC_POWERNV
3103 static void dump_opal_msglog(void)
3105 unsigned char buf[128];
3107 volatile loff_t pos = 0;
3109 if (!firmware_has_feature(FW_FEATURE_OPAL)) {
3110 printf("Machine is not running OPAL firmware.\n");
3114 if (setjmp(bus_error_jmp) != 0) {
3115 printf("Error dumping OPAL msglog!\n");
3119 catch_memory_errors = 1;
3122 xmon_start_pagination();
3123 while ((res = opal_msglog_copy(buf, pos, sizeof(buf) - 1))) {
3125 printf("Error dumping OPAL msglog! Error: %zd\n", res);
3132 xmon_end_pagination();
3135 /* wait a little while to see if we get a machine check */
3137 catch_memory_errors = 0;
3142 * Memory operations - move, set, print differences
3144 static unsigned long mdest; /* destination address */
3145 static unsigned long msrc; /* source address */
3146 static unsigned long mval; /* byte value to set memory to */
3147 static unsigned long mcount; /* # bytes to affect */
3148 static unsigned long mdiffs; /* max # differences to print */
3153 scanhex((void *)&mdest);
3154 if( termch != '\n' )
3156 scanhex((void *)(cmd == 's'? &mval: &msrc));
3157 if( termch != '\n' )
3159 scanhex((void *)&mcount);
3163 printf(xmon_ro_msg);
3166 memmove((void *)mdest, (void *)msrc, mcount);
3170 printf(xmon_ro_msg);
3173 memset((void *)mdest, mval, mcount);
3176 if( termch != '\n' )
3178 scanhex((void *)&mdiffs);
3179 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
3185 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
3190 for( n = nb; n > 0; --n )
3191 if( *p1++ != *p2++ )
3192 if( ++prt <= maxpr )
3193 printf("%px %.2x # %px %.2x\n", p1 - 1,
3194 p1[-1], p2 - 1, p2[-1]);
3196 printf("Total of %d differences\n", prt);
3199 static unsigned mend;
3200 static unsigned mask;
3206 unsigned char val[4];
3209 scanhex((void *)&mdest);
3210 if (termch != '\n') {
3212 scanhex((void *)&mend);
3213 if (termch != '\n') {
3215 scanhex((void *)&mval);
3217 if (termch != '\n') termch = 0;
3218 scanhex((void *)&mask);
3222 for (a = mdest; a < mend; a += 4) {
3223 if (mread(a, val, 4) == 4
3224 && ((GETWORD(val) ^ mval) & mask) == 0) {
3225 printf("%.16x: %.16x\n", a, GETWORD(val));
3232 static unsigned long mskip = 0x1000;
3233 static unsigned long mlim = 0xffffffff;
3243 if (termch != '\n') termch = 0;
3245 if (termch != '\n') termch = 0;
3248 for (a = mdest; a < mlim; a += mskip) {
3249 ok = mread(a, &v, 1);
3251 printf("%.8x .. ", a);
3252 } else if (!ok && ook)
3253 printf("%.8lx\n", a - mskip);
3259 printf("%.8lx\n", a - mskip);
3262 static void show_task(struct task_struct *volatile tsk)
3264 unsigned int p_state = READ_ONCE(tsk->__state);
3268 * Cloned from kdb_task_state_char(), which is not entirely
3269 * appropriate for calling from xmon. This could be moved
3270 * to a common, generic, routine used by both.
3272 state = (p_state == TASK_RUNNING) ? 'R' :
3273 (p_state & TASK_UNINTERRUPTIBLE) ? 'D' :
3274 (p_state & TASK_STOPPED) ? 'T' :
3275 (p_state & TASK_TRACED) ? 'C' :
3276 (tsk->exit_state & EXIT_ZOMBIE) ? 'Z' :
3277 (tsk->exit_state & EXIT_DEAD) ? 'E' :
3278 (p_state & TASK_INTERRUPTIBLE) ? 'S' : '?';
3280 printf("%16px %16lx %16px %6d %6d %c %2d %s\n", tsk,
3281 tsk->thread.ksp, tsk->thread.regs,
3282 tsk->pid, rcu_dereference(tsk->parent)->pid,
3283 state, task_cpu(tsk),
3287 #ifdef CONFIG_PPC_BOOK3S_64
3288 static void format_pte(void *ptep, unsigned long pte)
3290 pte_t entry = __pte(pte);
3292 printf("ptep @ 0x%016lx = 0x%016lx\n", (unsigned long)ptep, pte);
3293 printf("Maps physical address = 0x%016lx\n", pte & PTE_RPN_MASK);
3295 printf("Flags = %s%s%s%s%s\n",
3296 pte_young(entry) ? "Accessed " : "",
3297 pte_dirty(entry) ? "Dirty " : "",
3298 pte_read(entry) ? "Read " : "",
3299 pte_write(entry) ? "Write " : "",
3300 pte_exec(entry) ? "Exec " : "");
3303 static void show_pte(unsigned long addr)
3305 unsigned long tskv = 0;
3306 struct task_struct *volatile tsk = NULL;
3307 struct mm_struct *volatile mm;
3314 if (!scanhex(&tskv))
3317 tsk = (struct task_struct *)tskv;
3322 mm = tsk->active_mm;
3324 if (setjmp(bus_error_jmp) != 0) {
3325 catch_memory_errors = 0;
3326 printf("*** Error dumping pte for task %px\n", tsk);
3330 catch_memory_errors = 1;
3334 pgdp = pgd_offset_k(addr);
3336 pgdp = pgd_offset(mm, addr);
3338 p4dp = p4d_offset(pgdp, addr);
3340 if (p4d_none(*p4dp)) {
3341 printf("No valid P4D\n");
3345 if (p4d_is_leaf(*p4dp)) {
3346 format_pte(p4dp, p4d_val(*p4dp));
3350 printf("p4dp @ 0x%px = 0x%016lx\n", p4dp, p4d_val(*p4dp));
3352 pudp = pud_offset(p4dp, addr);
3354 if (pud_none(*pudp)) {
3355 printf("No valid PUD\n");
3359 if (pud_is_leaf(*pudp)) {
3360 format_pte(pudp, pud_val(*pudp));
3364 printf("pudp @ 0x%px = 0x%016lx\n", pudp, pud_val(*pudp));
3366 pmdp = pmd_offset(pudp, addr);
3368 if (pmd_none(*pmdp)) {
3369 printf("No valid PMD\n");
3373 if (pmd_is_leaf(*pmdp)) {
3374 format_pte(pmdp, pmd_val(*pmdp));
3377 printf("pmdp @ 0x%px = 0x%016lx\n", pmdp, pmd_val(*pmdp));
3379 ptep = pte_offset_map(pmdp, addr);
3380 if (!ptep || pte_none(*ptep)) {
3383 printf("no valid PTE\n");
3387 format_pte(ptep, pte_val(*ptep));
3392 catch_memory_errors = 0;
3395 static void show_pte(unsigned long addr)
3397 printf("show_pte not yet implemented\n");
3399 #endif /* CONFIG_PPC_BOOK3S_64 */
3401 static void show_tasks(void)
3404 struct task_struct *volatile tsk = NULL;
3406 printf(" task_struct ->thread.ksp ->thread.regs PID PPID S P CMD\n");
3409 tsk = (struct task_struct *)tskv;
3411 if (setjmp(bus_error_jmp) != 0) {
3412 catch_memory_errors = 0;
3413 printf("*** Error dumping task %px\n", tsk);
3417 catch_memory_errors = 1;
3423 for_each_process(tsk)
3428 catch_memory_errors = 0;
3431 static void proccall(void)
3433 unsigned long args[8];
3436 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
3437 unsigned long, unsigned long, unsigned long,
3438 unsigned long, unsigned long, unsigned long);
3441 if (!scanhex(&adrs))
3445 for (i = 0; i < 8; ++i)
3447 for (i = 0; i < 8; ++i) {
3448 if (!scanhex(&args[i]) || termch == '\n')
3452 func = (callfunc_t) adrs;
3454 if (setjmp(bus_error_jmp) == 0) {
3455 catch_memory_errors = 1;
3457 ret = func(args[0], args[1], args[2], args[3],
3458 args[4], args[5], args[6], args[7]);
3460 printf("return value is 0x%lx\n", ret);
3462 printf("*** %x exception occurred\n", fault_except);
3464 catch_memory_errors = 0;
3467 /* Input scanning routines */
3478 while( c == ' ' || c == '\t' )
3484 static const char *regnames[N_PTREGS] = {
3485 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
3486 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
3487 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
3488 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
3489 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
3495 "trap", "dar", "dsisr", "res"
3499 scanhex(unsigned long *vp)
3506 /* parse register name */
3510 for (i = 0; i < sizeof(regname) - 1; ++i) {
3519 i = match_string(regnames, N_PTREGS, regname);
3521 printf("invalid register name '%%%s'\n", regname);
3524 if (xmon_regs == NULL) {
3525 printf("regs not available\n");
3528 *vp = ((unsigned long *)xmon_regs)[i];
3532 /* skip leading "0x" if any */
3546 } else if (c == '$') {
3548 for (i=0; i<63; i++) {
3550 if (isspace(c) || c == '\0') {
3558 if (setjmp(bus_error_jmp) == 0) {
3559 catch_memory_errors = 1;
3561 *vp = kallsyms_lookup_name(tmpstr);
3564 catch_memory_errors = 0;
3566 printf("unknown symbol '%s'\n", tmpstr);
3599 static int hexdigit(int c)
3601 if( '0' <= c && c <= '9' )
3603 if( 'A' <= c && c <= 'F' )
3604 return c - ('A' - 10);
3605 if( 'a' <= c && c <= 'f' )
3606 return c - ('a' - 10);
3611 getstring(char *s, int size)
3627 } while( c != ' ' && c != '\t' && c != '\n' );
3632 static char line[256];
3633 static char *lineptr;
3644 if (lineptr == NULL || *lineptr == 0) {
3645 if (xmon_gets(line, sizeof(line)) == NULL) {
3655 take_input(char *str)
3664 int type = inchar();
3665 unsigned long addr, cpu;
3666 void __percpu *ptr = NULL;
3667 static char tmp[64];
3672 xmon_print_symbol(addr, ": ", "\n");
3677 if (setjmp(bus_error_jmp) == 0) {
3678 catch_memory_errors = 1;
3680 addr = kallsyms_lookup_name(tmp);
3682 printf("%s: %lx\n", tmp, addr);
3684 printf("Symbol '%s' not found.\n", tmp);
3687 catch_memory_errors = 0;
3692 if (setjmp(bus_error_jmp) == 0) {
3693 catch_memory_errors = 1;
3695 ptr = (void __percpu *)kallsyms_lookup_name(tmp);
3700 ptr >= (void __percpu *)__per_cpu_start &&
3701 ptr < (void __percpu *)__per_cpu_end)
3703 if (scanhex(&cpu) && cpu < num_possible_cpus()) {
3704 addr = (unsigned long)per_cpu_ptr(ptr, cpu);
3706 cpu = raw_smp_processor_id();
3707 addr = (unsigned long)this_cpu_ptr(ptr);
3710 printf("%s for cpu 0x%lx: %lx\n", tmp, cpu, addr);
3712 printf("Percpu symbol '%s' not found.\n", tmp);
3715 catch_memory_errors = 0;
3722 /* Print an address in numeric and symbolic form (if possible) */
3723 static void xmon_print_symbol(unsigned long address, const char *mid,
3727 const char *volatile name = NULL;
3728 unsigned long offset, size;
3730 printf(REG, address);
3731 if (setjmp(bus_error_jmp) == 0) {
3732 catch_memory_errors = 1;
3734 name = kallsyms_lookup(address, &size, &offset, &modname,
3737 /* wait a little while to see if we get a machine check */
3741 catch_memory_errors = 0;
3744 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
3746 printf(" [%s]", modname);
3748 printf("%s", after);
3751 #ifdef CONFIG_PPC_64S_HASH_MMU
3752 void dump_segments(void)
3755 unsigned long esid,vsid;
3758 printf("SLB contents of cpu 0x%x\n", smp_processor_id());
3760 for (i = 0; i < mmu_slb_size; i++) {
3761 asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i));
3762 asm volatile("slbmfev %0,%1" : "=r" (vsid) : "r" (i));
3767 printf("%02d %016lx %016lx", i, esid, vsid);
3769 if (!(esid & SLB_ESID_V)) {
3774 llp = vsid & SLB_VSID_LLP;
3775 if (vsid & SLB_VSID_B_1T) {
3776 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
3778 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T,
3781 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
3783 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT,
3790 #ifdef CONFIG_PPC_BOOK3S_32
3791 void dump_segments(void)
3796 for (i = 0; i < 16; ++i)
3797 printf(" %x", mfsr(i << 28));
3803 static void dump_tlb_44x(void)
3807 for (i = 0; i < PPC44x_TLB_SIZE; i++) {
3808 unsigned long w0,w1,w2;
3809 asm volatile("tlbre %0,%1,0" : "=r" (w0) : "r" (i));
3810 asm volatile("tlbre %0,%1,1" : "=r" (w1) : "r" (i));
3811 asm volatile("tlbre %0,%1,2" : "=r" (w2) : "r" (i));
3812 printf("[%02x] %08lx %08lx %08lx ", i, w0, w1, w2);
3813 if (w0 & PPC44x_TLB_VALID) {
3814 printf("V %08lx -> %01lx%08lx %c%c%c%c%c",
3815 w0 & PPC44x_TLB_EPN_MASK,
3816 w1 & PPC44x_TLB_ERPN_MASK,
3817 w1 & PPC44x_TLB_RPN_MASK,
3818 (w2 & PPC44x_TLB_W) ? 'W' : 'w',
3819 (w2 & PPC44x_TLB_I) ? 'I' : 'i',
3820 (w2 & PPC44x_TLB_M) ? 'M' : 'm',
3821 (w2 & PPC44x_TLB_G) ? 'G' : 'g',
3822 (w2 & PPC44x_TLB_E) ? 'E' : 'e');
3827 #endif /* CONFIG_44x */
3829 #ifdef CONFIG_PPC_BOOK3E_64
3830 static void dump_tlb_book3e(void)
3834 int i, tlb, ntlbs, pidsz, lpidsz, rasz;
3836 static const char *pgsz_names[] = {
3871 /* Gather some infos about the MMU */
3872 mmucfg = mfspr(SPRN_MMUCFG);
3873 mmu_version = (mmucfg & 3) + 1;
3874 ntlbs = ((mmucfg >> 2) & 3) + 1;
3875 pidsz = ((mmucfg >> 6) & 0x1f) + 1;
3876 lpidsz = (mmucfg >> 24) & 0xf;
3877 rasz = (mmucfg >> 16) & 0x7f;
3878 printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n",
3879 mmu_version, ntlbs, pidsz, lpidsz, rasz);
3880 ramask = (1ull << rasz) - 1;
3882 for (tlb = 0; tlb < ntlbs; tlb++) {
3884 int nent, assoc, new_cc = 1;
3885 printf("TLB %d:\n------\n", tlb);
3888 tlbcfg = mfspr(SPRN_TLB0CFG);
3891 tlbcfg = mfspr(SPRN_TLB1CFG);
3894 tlbcfg = mfspr(SPRN_TLB2CFG);
3897 tlbcfg = mfspr(SPRN_TLB3CFG);
3900 printf("Unsupported TLB number !\n");
3903 nent = tlbcfg & 0xfff;
3904 assoc = (tlbcfg >> 24) & 0xff;
3905 for (i = 0; i < nent; i++) {
3906 u32 mas0 = MAS0_TLBSEL(tlb);
3907 u32 mas1 = MAS1_TSIZE(BOOK3E_PAGESZ_4K);
3910 int esel = i, cc = i;
3918 mas0 |= MAS0_ESEL(esel);
3919 mtspr(SPRN_MAS0, mas0);
3920 mtspr(SPRN_MAS1, mas1);
3921 mtspr(SPRN_MAS2, mas2);
3922 asm volatile("tlbre 0,0,0" : : : "memory");
3923 mas1 = mfspr(SPRN_MAS1);
3924 mas2 = mfspr(SPRN_MAS2);
3925 mas7_mas3 = mfspr(SPRN_MAS7_MAS3);
3926 if (assoc && (i % assoc) == 0)
3928 if (!(mas1 & MAS1_VALID))
3931 printf("%04x- ", i);
3933 printf("%04x-%c", cc, 'A' + esel);
3935 printf(" |%c", 'A' + esel);
3937 printf(" %016llx %04x %s %c%c AS%c",
3939 (mas1 >> 16) & 0x3fff,
3940 pgsz_names[(mas1 >> 7) & 0x1f],
3941 mas1 & MAS1_IND ? 'I' : ' ',
3942 mas1 & MAS1_IPROT ? 'P' : ' ',
3943 mas1 & MAS1_TS ? '1' : '0');
3944 printf(" %c%c%c%c%c%c%c",
3945 mas2 & MAS2_X0 ? 'a' : ' ',
3946 mas2 & MAS2_X1 ? 'v' : ' ',
3947 mas2 & MAS2_W ? 'w' : ' ',
3948 mas2 & MAS2_I ? 'i' : ' ',
3949 mas2 & MAS2_M ? 'm' : ' ',
3950 mas2 & MAS2_G ? 'g' : ' ',
3951 mas2 & MAS2_E ? 'e' : ' ');
3952 printf(" %016llx", mas7_mas3 & ramask & ~0x7ffull);
3953 if (mas1 & MAS1_IND)
3955 pgsz_names[(mas7_mas3 >> 1) & 0x1f]);
3957 printf(" U%c%c%c S%c%c%c\n",
3958 mas7_mas3 & MAS3_UX ? 'x' : ' ',
3959 mas7_mas3 & MAS3_UW ? 'w' : ' ',
3960 mas7_mas3 & MAS3_UR ? 'r' : ' ',
3961 mas7_mas3 & MAS3_SX ? 'x' : ' ',
3962 mas7_mas3 & MAS3_SW ? 'w' : ' ',
3963 mas7_mas3 & MAS3_SR ? 'r' : ' ');
3967 #endif /* CONFIG_PPC_BOOK3E_64 */
3969 static void xmon_init(int enable)
3973 __debugger_ipi = xmon_ipi;
3974 __debugger_bpt = xmon_bpt;
3975 __debugger_sstep = xmon_sstep;
3976 __debugger_iabr_match = xmon_iabr_match;
3977 __debugger_break_match = xmon_break_match;
3978 __debugger_fault_handler = xmon_fault_handler;
3981 __debugger_ipi = NULL;
3982 __debugger_bpt = NULL;
3983 __debugger_sstep = NULL;
3984 __debugger_iabr_match = NULL;
3985 __debugger_break_match = NULL;
3986 __debugger_fault_handler = NULL;
3990 #ifdef CONFIG_MAGIC_SYSRQ
3991 static void sysrq_handle_xmon(u8 key)
3993 if (xmon_is_locked_down()) {
3998 /* ensure xmon is enabled */
4000 debugger(get_irq_regs());
4005 static const struct sysrq_key_op sysrq_xmon_op = {
4006 .handler = sysrq_handle_xmon,
4007 .help_msg = "xmon(x)",
4008 .action_msg = "Entering xmon",
4011 static int __init setup_xmon_sysrq(void)
4013 register_sysrq_key('x', &sysrq_xmon_op);
4016 device_initcall(setup_xmon_sysrq);
4017 #endif /* CONFIG_MAGIC_SYSRQ */
4019 static void clear_all_bpt(void)
4023 /* clear/unpatch all breakpoints */
4027 /* Disable all breakpoints */
4028 for (i = 0; i < NBPTS; ++i)
4029 bpts[i].enabled = 0;
4031 /* Clear any data or iabr breakpoints */
4033 for (i = 0; i < nr_wp_slots(); i++)
4034 dabr[i].enabled = 0;
4037 #ifdef CONFIG_DEBUG_FS
4038 static int xmon_dbgfs_set(void *data, u64 val)
4043 /* make sure all breakpoints removed when disabling */
4047 printf("xmon: All breakpoints cleared\n");
4048 release_output_lock();
4054 static int xmon_dbgfs_get(void *data, u64 *val)
4060 DEFINE_SIMPLE_ATTRIBUTE(xmon_dbgfs_ops, xmon_dbgfs_get,
4061 xmon_dbgfs_set, "%llu\n");
4063 static int __init setup_xmon_dbgfs(void)
4065 debugfs_create_file("xmon", 0600, arch_debugfs_dir, NULL,
4069 device_initcall(setup_xmon_dbgfs);
4070 #endif /* CONFIG_DEBUG_FS */
4072 static int xmon_early __initdata;
4074 static int __init early_parse_xmon(char *p)
4076 if (xmon_is_locked_down()) {
4080 } else if (!p || strncmp(p, "early", 5) == 0) {
4081 /* just "xmon" is equivalent to "xmon=early" */
4085 } else if (strncmp(p, "on", 2) == 0) {
4088 } else if (strncmp(p, "rw", 2) == 0) {
4092 } else if (strncmp(p, "ro", 2) == 0) {
4096 } else if (strncmp(p, "off", 3) == 0)
4103 early_param("xmon", early_parse_xmon);
4105 void __init xmon_setup(void)
4113 #ifdef CONFIG_SPU_BASE
4117 u64 saved_mfc_sr1_RW;
4118 u32 saved_spu_runcntl_RW;
4119 unsigned long dump_addr;
4123 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
4125 static struct spu_info spu_info[XMON_NUM_SPUS];
4127 void __init xmon_register_spus(struct list_head *list)
4131 list_for_each_entry(spu, list, full_list) {
4132 if (spu->number >= XMON_NUM_SPUS) {
4137 spu_info[spu->number].spu = spu;
4138 spu_info[spu->number].stopped_ok = 0;
4139 spu_info[spu->number].dump_addr = (unsigned long)
4140 spu_info[spu->number].spu->local_store;
4144 static void stop_spus(void)
4150 for (i = 0; i < XMON_NUM_SPUS; i++) {
4151 if (!spu_info[i].spu)
4154 if (setjmp(bus_error_jmp) == 0) {
4155 catch_memory_errors = 1;
4158 spu = spu_info[i].spu;
4160 spu_info[i].saved_spu_runcntl_RW =
4161 in_be32(&spu->problem->spu_runcntl_RW);
4163 tmp = spu_mfc_sr1_get(spu);
4164 spu_info[i].saved_mfc_sr1_RW = tmp;
4166 tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
4167 spu_mfc_sr1_set(spu, tmp);
4172 spu_info[i].stopped_ok = 1;
4174 printf("Stopped spu %.2d (was %s)\n", i,
4175 spu_info[i].saved_spu_runcntl_RW ?
4176 "running" : "stopped");
4178 catch_memory_errors = 0;
4179 printf("*** Error stopping spu %.2d\n", i);
4181 catch_memory_errors = 0;
4185 static void restart_spus(void)
4190 for (i = 0; i < XMON_NUM_SPUS; i++) {
4191 if (!spu_info[i].spu)
4194 if (!spu_info[i].stopped_ok) {
4195 printf("*** Error, spu %d was not successfully stopped"
4196 ", not restarting\n", i);
4200 if (setjmp(bus_error_jmp) == 0) {
4201 catch_memory_errors = 1;
4204 spu = spu_info[i].spu;
4205 spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
4206 out_be32(&spu->problem->spu_runcntl_RW,
4207 spu_info[i].saved_spu_runcntl_RW);
4212 printf("Restarted spu %.2d\n", i);
4214 catch_memory_errors = 0;
4215 printf("*** Error restarting spu %.2d\n", i);
4217 catch_memory_errors = 0;
4221 #define DUMP_WIDTH 23
4222 #define DUMP_VALUE(format, field, value) \
4224 if (setjmp(bus_error_jmp) == 0) { \
4225 catch_memory_errors = 1; \
4227 printf(" %-*s = "format"\n", DUMP_WIDTH, \
4232 catch_memory_errors = 0; \
4233 printf(" %-*s = *** Error reading field.\n", \
4234 DUMP_WIDTH, #field); \
4236 catch_memory_errors = 0; \
4239 #define DUMP_FIELD(obj, format, field) \
4240 DUMP_VALUE(format, field, obj->field)
4242 static void dump_spu_fields(struct spu *spu)
4244 printf("Dumping spu fields at address %p:\n", spu);
4246 DUMP_FIELD(spu, "0x%x", number);
4247 DUMP_FIELD(spu, "%s", name);
4248 DUMP_FIELD(spu, "0x%lx", local_store_phys);
4249 DUMP_FIELD(spu, "0x%p", local_store);
4250 DUMP_FIELD(spu, "0x%lx", ls_size);
4251 DUMP_FIELD(spu, "0x%x", node);
4252 DUMP_FIELD(spu, "0x%lx", flags);
4253 DUMP_FIELD(spu, "%llu", class_0_pending);
4254 DUMP_FIELD(spu, "0x%llx", class_0_dar);
4255 DUMP_FIELD(spu, "0x%llx", class_1_dar);
4256 DUMP_FIELD(spu, "0x%llx", class_1_dsisr);
4257 DUMP_FIELD(spu, "0x%x", irqs[0]);
4258 DUMP_FIELD(spu, "0x%x", irqs[1]);
4259 DUMP_FIELD(spu, "0x%x", irqs[2]);
4260 DUMP_FIELD(spu, "0x%x", slb_replace);
4261 DUMP_FIELD(spu, "%d", pid);
4262 DUMP_FIELD(spu, "0x%p", mm);
4263 DUMP_FIELD(spu, "0x%p", ctx);
4264 DUMP_FIELD(spu, "0x%p", rq);
4265 DUMP_FIELD(spu, "0x%llx", timestamp);
4266 DUMP_FIELD(spu, "0x%lx", problem_phys);
4267 DUMP_FIELD(spu, "0x%p", problem);
4268 DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
4269 in_be32(&spu->problem->spu_runcntl_RW));
4270 DUMP_VALUE("0x%x", problem->spu_status_R,
4271 in_be32(&spu->problem->spu_status_R));
4272 DUMP_VALUE("0x%x", problem->spu_npc_RW,
4273 in_be32(&spu->problem->spu_npc_RW));
4274 DUMP_FIELD(spu, "0x%p", priv2);
4275 DUMP_FIELD(spu, "0x%p", pdata);
4278 static int spu_inst_dump(unsigned long adr, long count, int praddr)
4280 return generic_inst_dump(adr, count, praddr, print_insn_spu);
4283 static void dump_spu_ls(unsigned long num, int subcmd)
4285 unsigned long offset, addr, ls_addr;
4287 if (setjmp(bus_error_jmp) == 0) {
4288 catch_memory_errors = 1;
4290 ls_addr = (unsigned long)spu_info[num].spu->local_store;
4294 catch_memory_errors = 0;
4295 printf("*** Error: accessing spu info for spu %ld\n", num);
4298 catch_memory_errors = 0;
4300 if (scanhex(&offset))
4301 addr = ls_addr + offset;
4303 addr = spu_info[num].dump_addr;
4305 if (addr >= ls_addr + LS_SIZE) {
4306 printf("*** Error: address outside of local store\n");
4312 addr += spu_inst_dump(addr, 16, 1);
4322 spu_info[num].dump_addr = addr;
4325 static int do_spu_cmd(void)
4327 static unsigned long num = 0;
4328 int cmd, subcmd = 0;
4340 if (isxdigit(subcmd) || subcmd == '\n')
4345 if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
4346 printf("*** Error: invalid spu number\n");
4352 dump_spu_fields(spu_info[num].spu);
4355 dump_spu_ls(num, subcmd);
4366 #else /* ! CONFIG_SPU_BASE */
4367 static int do_spu_cmd(void)