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>
65 #include "xmon_bpts.h"
68 static cpumask_t cpus_in_xmon = CPU_MASK_NONE;
69 static unsigned long xmon_taken = 1;
70 static int xmon_owner;
72 static int xmon_batch;
73 static unsigned long xmon_batch_start_cpu;
74 static cpumask_t xmon_batch_cpus = CPU_MASK_NONE;
77 #endif /* CONFIG_SMP */
79 #ifdef CONFIG_PPC_PSERIES
80 static int set_indicator_token = RTAS_UNKNOWN_SERVICE;
82 static unsigned long in_xmon __read_mostly = 0;
83 static int xmon_on = IS_ENABLED(CONFIG_XMON_DEFAULT);
84 static bool xmon_is_ro = IS_ENABLED(CONFIG_XMON_DEFAULT_RO_MODE);
86 static unsigned long adrs;
88 #define MAX_DUMP (64 * 1024)
89 static unsigned long ndump = 64;
90 #define MAX_IDUMP (MAX_DUMP >> 2)
91 static unsigned long nidump = 16;
92 static unsigned long ncsum = 4096;
94 static char tmpstr[128];
95 static int tracing_enabled;
97 static long bus_error_jmp[JMP_BUF_LEN];
98 static int catch_memory_errors;
99 static int catch_spr_faults;
100 static long *xmon_fault_jmp[NR_CPUS];
102 /* Breakpoint stuff */
104 unsigned long address;
111 /* Bits in bpt.enabled */
116 static struct bpt bpts[NBPTS];
117 static struct bpt dabr[HBP_NUM_MAX];
118 static struct bpt *iabr;
119 static unsigned bpinstr = 0x7fe00008; /* trap */
121 #define BP_NUM(bp) ((bp) - bpts + 1)
124 static int cmds(struct pt_regs *);
125 static int mread(unsigned long, void *, int);
126 static int mwrite(unsigned long, void *, int);
127 static int mread_instr(unsigned long, ppc_inst_t *);
128 static int handle_fault(struct pt_regs *);
129 static void byterev(unsigned char *, int);
130 static void memex(void);
131 static int bsesc(void);
132 static void dump(void);
133 static void show_pte(unsigned long);
134 static void prdump(unsigned long, long);
135 static int ppc_inst_dump(unsigned long, long, int);
136 static void dump_log_buf(void);
139 static int xmon_switch_cpu(unsigned long);
140 static int xmon_batch_next_cpu(void);
141 static int batch_cmds(struct pt_regs *);
144 #ifdef CONFIG_PPC_POWERNV
145 static void dump_opal_msglog(void);
147 static inline void dump_opal_msglog(void)
149 printf("Machine is not running OPAL firmware.\n");
153 static void backtrace(struct pt_regs *);
154 static void excprint(struct pt_regs *);
155 static void prregs(struct pt_regs *);
156 static void memops(int);
157 static void memlocate(void);
158 static void memzcan(void);
159 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
161 int scanhex(unsigned long *valp);
162 static void scannl(void);
163 static int hexdigit(int);
164 void getstring(char *, int);
165 static void flush_input(void);
166 static int inchar(void);
167 static void take_input(char *);
168 static int read_spr(int, unsigned long *);
169 static void write_spr(int, unsigned long);
170 static void super_regs(void);
171 static void remove_bpts(void);
172 static void insert_bpts(void);
173 static void remove_cpu_bpts(void);
174 static void insert_cpu_bpts(void);
175 static struct bpt *at_breakpoint(unsigned long pc);
176 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
177 static int do_step(struct pt_regs *);
178 static void bpt_cmds(void);
179 static void cacheflush(void);
180 static int cpu_cmd(void);
181 static void csum(void);
182 static void bootcmds(void);
183 static void proccall(void);
184 static void show_tasks(void);
185 void dump_segments(void);
186 static void symbol_lookup(void);
187 static void xmon_show_stack(unsigned long sp, unsigned long lr,
189 static void xmon_print_symbol(unsigned long address, const char *mid,
191 static const char *getvecname(unsigned long vec);
193 static int do_spu_cmd(void);
196 static void dump_tlb_44x(void);
198 #ifdef CONFIG_PPC_BOOK3E
199 static void dump_tlb_book3e(void);
202 static void clear_all_bpt(void);
210 #ifdef __LITTLE_ENDIAN__
211 #define GETWORD(v) (((v)[3] << 24) + ((v)[2] << 16) + ((v)[1] << 8) + (v)[0])
213 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
216 static const char *xmon_ro_msg = "Operation disabled: xmon in read-only mode\n";
218 static char *help_string = "\
220 b show breakpoints\n\
221 bd set data breakpoint\n\
222 bi set instruction breakpoint\n\
223 bc clear breakpoint\n"
226 c print cpus stopped in xmon\n\
227 c# try to switch to cpu number h (in hex)\n\
228 c# $ run command '$' (one of 'r','S' or 't') on all cpus in xmon\n"
233 d1 dump 1 byte values\n\
234 d2 dump 2 byte values\n\
235 d4 dump 4 byte values\n\
236 d8 dump 8 byte values\n\
237 di dump instructions\n\
238 df dump float values\n\
239 dd dump double values\n\
240 dl dump the kernel log buffer\n"
241 #ifdef CONFIG_PPC_POWERNV
243 do dump the OPAL message log\n"
247 dp[#] dump paca for current cpu, or cpu #\n\
248 dpa dump paca for all possible cpus\n"
251 dr dump stream of raw bytes\n\
252 dv dump virtual address translation \n\
253 dt dump the tracing buffers (uses printk)\n\
254 dtc dump the tracing buffers for current CPU (uses printk)\n\
256 #ifdef CONFIG_PPC_POWERNV
257 " dx# dump xive on CPU #\n\
258 dxi# dump xive irq state #\n\
259 dxa dump xive on all CPUs\n"
261 " e print exception information\n\
263 la lookup symbol+offset of specified address\n\
264 ls lookup address of specified symbol\n\
265 lp s [#] lookup address of percpu symbol s for current cpu, or cpu #\n\
266 m examine/change memory\n\
267 mm move a block of memory\n\
268 ms set a block of memory\n\
269 md compare two blocks of memory\n\
270 ml locate a block of memory\n\
271 mz zero a block of memory\n\
272 mi show information about memory allocation\n\
273 p call a procedure\n\
274 P list processes/tasks\n\
277 #ifdef CONFIG_SPU_BASE
278 " ss stop execution on all spus\n\
279 sr restore execution on stopped spus\n\
280 sf # dump spu fields for spu # (in hex)\n\
281 sd # dump spu local store for spu # (in hex)\n\
282 sdi # disassemble spu local store for spu # (in hex)\n"
284 " S print special registers\n\
287 Sw #v write v to SPR #\n\
289 x exit monitor and recover\n\
290 X exit monitor and don't recover\n"
291 #if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_BOOK3E)
292 " u dump segment table or SLB\n"
293 #elif defined(CONFIG_PPC_BOOK3S_32)
294 " u dump segment registers\n"
295 #elif defined(CONFIG_44x) || defined(CONFIG_PPC_BOOK3E)
298 " U show uptime information\n"
300 " # n limit output to n lines per page (for dp, dpa, dl)\n"
305 #ifdef CONFIG_SECURITY
306 static bool xmon_is_locked_down(void)
308 static bool lockdown;
311 lockdown = !!security_locked_down(LOCKDOWN_XMON_RW);
313 printf("xmon: Disabled due to kernel lockdown\n");
319 xmon_is_ro = !!security_locked_down(LOCKDOWN_XMON_WR);
321 printf("xmon: Read-only due to kernel lockdown\n");
326 #else /* CONFIG_SECURITY */
327 static inline bool xmon_is_locked_down(void)
333 static struct pt_regs *xmon_regs;
335 static inline void sync(void)
337 asm volatile("sync; isync");
340 static inline void cflush(void *p)
342 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
345 static inline void cinval(void *p)
347 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
351 * write_ciabr() - write the CIABR SPR
352 * @ciabr: The value to write.
354 * This function writes a value to the CIARB register either directly
355 * through mtspr instruction if the kernel is in HV privilege mode or
356 * call a hypervisor function to achieve the same in case the kernel
357 * is in supervisor privilege mode.
359 static void write_ciabr(unsigned long ciabr)
361 if (!cpu_has_feature(CPU_FTR_ARCH_207S))
364 if (cpu_has_feature(CPU_FTR_HVMODE)) {
365 mtspr(SPRN_CIABR, ciabr);
368 plpar_set_ciabr(ciabr);
372 * set_ciabr() - set the CIABR
373 * @addr: The value to set.
375 * This function sets the correct privilege value into the HW
376 * breakpoint address before writing it up in the CIABR register.
378 static void set_ciabr(unsigned long addr)
382 if (cpu_has_feature(CPU_FTR_HVMODE))
383 addr |= CIABR_PRIV_HYPER;
385 addr |= CIABR_PRIV_SUPER;
390 * Disable surveillance (the service processor watchdog function)
391 * while we are in xmon.
392 * XXX we should re-enable it when we leave. :)
394 #define SURVEILLANCE_TOKEN 9000
396 static inline void disable_surveillance(void)
398 #ifdef CONFIG_PPC_PSERIES
399 /* Since this can't be a module, args should end up below 4GB. */
400 static struct rtas_args args;
403 * At this point we have got all the cpus we can into
404 * xmon, so there is hopefully no other cpu calling RTAS
405 * at the moment, even though we don't take rtas.lock.
406 * If we did try to take rtas.lock there would be a
407 * real possibility of deadlock.
409 if (set_indicator_token == RTAS_UNKNOWN_SERVICE)
412 rtas_call_unlocked(&args, set_indicator_token, 3, 1, NULL,
413 SURVEILLANCE_TOKEN, 0, 0);
415 #endif /* CONFIG_PPC_PSERIES */
419 static int xmon_speaker;
421 static void get_output_lock(void)
423 int me = smp_processor_id() + 0x100;
424 int last_speaker = 0, prev;
427 if (xmon_speaker == me)
431 last_speaker = cmpxchg(&xmon_speaker, 0, me);
432 if (last_speaker == 0)
436 * Wait a full second for the lock, we might be on a slow
437 * console, but check every 100us.
440 while (xmon_speaker == last_speaker) {
446 /* hostile takeover */
447 prev = cmpxchg(&xmon_speaker, last_speaker, me);
448 if (prev == last_speaker)
455 static void release_output_lock(void)
460 int cpus_are_in_xmon(void)
462 return !cpumask_empty(&cpus_in_xmon);
465 static bool wait_for_other_cpus(int ncpus)
467 unsigned long timeout;
469 /* We wait for 2s, which is a metric "little while" */
470 for (timeout = 20000; timeout != 0; --timeout) {
471 if (cpumask_weight(&cpus_in_xmon) >= ncpus)
479 #else /* CONFIG_SMP */
480 static inline void get_output_lock(void) {}
481 static inline void release_output_lock(void) {}
484 static void xmon_touch_watchdogs(void)
486 touch_softlockup_watchdog_sync();
487 rcu_cpu_stall_reset();
488 touch_nmi_watchdog();
491 static int xmon_core(struct pt_regs *regs, volatile int fromipi)
493 volatile int cmd = 0;
494 struct bpt *volatile bp;
495 long recurse_jmp[JMP_BUF_LEN];
497 unsigned long offset;
504 local_irq_save(flags);
507 locked_down = xmon_is_locked_down();
510 tracing_enabled = tracing_is_on();
514 bp = in_breakpoint_table(regs->nip, &offset);
516 regs_set_return_ip(regs, bp->address + offset);
517 atomic_dec(&bp->ref_count);
523 cpu = smp_processor_id();
524 if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
526 * We catch SPR read/write faults here because the 0x700, 0xf60
527 * etc. handlers don't call debugger_fault_handler().
529 if (catch_spr_faults)
530 longjmp(bus_error_jmp, 1);
533 printf("cpu 0x%x: Exception %lx %s in xmon, "
534 "returning to main loop\n",
535 cpu, regs->trap, getvecname(TRAP(regs)));
536 release_output_lock();
537 longjmp(xmon_fault_jmp[cpu], 1);
540 if (setjmp(recurse_jmp) != 0) {
541 if (!in_xmon || !xmon_gate) {
543 printf("xmon: WARNING: bad recursive fault "
544 "on cpu 0x%x\n", cpu);
545 release_output_lock();
548 secondary = !(xmon_taken && cpu == xmon_owner);
552 xmon_fault_jmp[cpu] = recurse_jmp;
555 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT))
556 bp = at_breakpoint(regs->nip);
557 if (bp || regs_is_unrecoverable(regs))
565 printf("cpu 0x%x stopped at breakpoint 0x%tx (",
567 xmon_print_symbol(regs->nip, " ", ")\n");
569 if (regs_is_unrecoverable(regs))
570 printf("WARNING: exception is not recoverable, "
572 release_output_lock();
575 cpumask_set_cpu(cpu, &cpus_in_xmon);
580 while (secondary && !xmon_gate) {
586 secondary = test_and_set_bit(0, &in_xmon);
589 touch_nmi_watchdog();
593 if (!secondary && !xmon_gate) {
594 /* we are the first cpu to come in */
595 /* interrupt other cpu(s) */
596 int ncpus = num_online_cpus();
602 * A system reset (trap == 0x100) can be triggered on
603 * all CPUs, so when we come in via 0x100 try waiting
604 * for the other CPUs to come in before we send the
605 * debugger break (IPI). This is similar to
606 * crash_kexec_secondary().
608 if (TRAP(regs) != INTERRUPT_SYSTEM_RESET || !wait_for_other_cpus(ncpus))
609 smp_send_debugger_break();
611 wait_for_other_cpus(ncpus);
614 disable_surveillance();
617 /* for breakpoint or single step, print curr insn */
618 if (bp || TRAP(regs) == INTERRUPT_TRACE)
619 ppc_inst_dump(regs->nip, 1, 0);
620 printf("enter ? for help\n");
626 touch_nmi_watchdog();
633 if (cpu == xmon_owner) {
634 if (!test_and_set_bit(0, &xmon_taken)) {
640 while (cpu == xmon_owner)
644 touch_nmi_watchdog();
649 cmd = batch_cmds(regs);
651 if (!locked_down && cmd)
653 if (locked_down || cmd != 0) {
661 /* have switched to some other cpu */
666 cpumask_clear_cpu(cpu, &cpus_in_xmon);
667 xmon_fault_jmp[cpu] = NULL;
669 /* UP is simple... */
671 printf("Exception %lx %s in xmon, returning to main loop\n",
672 regs->trap, getvecname(TRAP(regs)));
673 longjmp(xmon_fault_jmp[0], 1);
675 if (setjmp(recurse_jmp) == 0) {
676 xmon_fault_jmp[0] = recurse_jmp;
680 bp = at_breakpoint(regs->nip);
682 printf("Stopped at breakpoint %tx (", BP_NUM(bp));
683 xmon_print_symbol(regs->nip, " ", ")\n");
685 if (regs_is_unrecoverable(regs))
686 printf("WARNING: exception is not recoverable, "
689 disable_surveillance();
691 /* for breakpoint or single step, print current insn */
692 if (bp || TRAP(regs) == INTERRUPT_TRACE)
693 ppc_inst_dump(regs->nip, 1, 0);
694 printf("enter ? for help\n");
706 if (regs->msr & MSR_DE) {
707 bp = at_breakpoint(regs->nip);
709 regs_set_return_ip(regs, (unsigned long) &bp->instr[0]);
710 atomic_inc(&bp->ref_count);
714 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
715 bp = at_breakpoint(regs->nip);
717 int stepped = emulate_step(regs, ppc_inst_read(bp->instr));
719 regs_set_return_ip(regs, (unsigned long) &bp->instr[0]);
720 atomic_inc(&bp->ref_count);
721 } else if (stepped < 0) {
722 printf("Couldn't single-step %s instruction\n",
723 IS_RFID(ppc_inst_read(bp->instr))? "rfid": "mtmsrd");
733 xmon_touch_watchdogs();
734 local_irq_restore(flags);
736 return cmd != 'X' && cmd != EOF;
739 int xmon(struct pt_regs *excp)
744 ppc_save_regs(®s);
748 return xmon_core(excp, 0);
752 irqreturn_t xmon_irq(int irq, void *d)
755 local_irq_save(flags);
756 printf("Keyboard interrupt\n");
757 xmon(get_irq_regs());
758 local_irq_restore(flags);
762 static int xmon_bpt(struct pt_regs *regs)
765 unsigned long offset;
767 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
770 /* Are we at the trap at bp->instr[1] for some bp? */
771 bp = in_breakpoint_table(regs->nip, &offset);
772 if (bp != NULL && (offset == 4 || offset == 8)) {
773 regs_set_return_ip(regs, bp->address + offset);
774 atomic_dec(&bp->ref_count);
778 /* Are we at a breakpoint? */
779 bp = at_breakpoint(regs->nip);
788 static int xmon_sstep(struct pt_regs *regs)
796 static int xmon_break_match(struct pt_regs *regs)
800 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
802 for (i = 0; i < nr_wp_slots(); i++) {
813 static int xmon_iabr_match(struct pt_regs *regs)
815 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
823 static int xmon_ipi(struct pt_regs *regs)
826 if (in_xmon && !cpumask_test_cpu(smp_processor_id(), &cpus_in_xmon))
832 static int xmon_fault_handler(struct pt_regs *regs)
835 unsigned long offset;
837 if (in_xmon && catch_memory_errors)
838 handle_fault(regs); /* doesn't return */
840 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
841 bp = in_breakpoint_table(regs->nip, &offset);
843 regs_set_return_ip(regs, bp->address + offset);
844 atomic_dec(&bp->ref_count);
851 /* Force enable xmon if not already enabled */
852 static inline void force_enable_xmon(void)
854 /* Enable xmon hooks if needed */
856 printf("xmon: Enabling debugger hooks\n");
861 static struct bpt *at_breakpoint(unsigned long pc)
864 struct bpt *volatile bp;
867 for (i = 0; i < NBPTS; ++i, ++bp)
868 if (bp->enabled && pc == bp->address)
873 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
877 off = nip - (unsigned long)bpt_table;
878 if (off >= sizeof(bpt_table))
880 *offp = off & (BPT_SIZE - 1);
883 return bpts + (off / BPT_SIZE);
886 static struct bpt *new_breakpoint(unsigned long a)
891 bp = at_breakpoint(a);
895 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
896 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
898 bp->instr = (void *)(bpt_table + ((bp - bpts) * BPT_WORDS));
903 printf("Sorry, no free breakpoints. Please clear one first.\n");
907 static void insert_bpts(void)
910 ppc_inst_t instr, instr2;
911 struct bpt *bp, *bp2;
914 for (i = 0; i < NBPTS; ++i, ++bp) {
915 if ((bp->enabled & (BP_TRAP|BP_CIABR)) == 0)
917 if (!mread_instr(bp->address, &instr)) {
918 printf("Couldn't read instruction at %lx, "
919 "disabling breakpoint there\n", bp->address);
923 if (!can_single_step(ppc_inst_val(instr))) {
924 printf("Breakpoint at %lx is on an instruction that can't be single stepped, disabling it\n",
930 * Check the address is not a suffix by looking for a prefix in
933 if (mread_instr(bp->address - 4, &instr2) == 8) {
934 printf("Breakpoint at %lx is on the second word of a prefixed instruction, disabling it\n",
940 * We might still be a suffix - if the prefix has already been
941 * replaced by a breakpoint we won't catch it with the above
944 bp2 = at_breakpoint(bp->address - 4);
945 if (bp2 && ppc_inst_prefixed(ppc_inst_read(bp2->instr))) {
946 printf("Breakpoint at %lx is on the second word of a prefixed instruction, disabling it\n",
952 patch_instruction(bp->instr, instr);
953 patch_instruction(ppc_inst_next(bp->instr, bp->instr),
955 if (bp->enabled & BP_CIABR)
957 if (patch_instruction((u32 *)bp->address,
958 ppc_inst(bpinstr)) != 0) {
959 printf("Couldn't write instruction at %lx, "
960 "disabling breakpoint there\n", bp->address);
961 bp->enabled &= ~BP_TRAP;
967 static void insert_cpu_bpts(void)
970 struct arch_hw_breakpoint brk;
972 for (i = 0; i < nr_wp_slots(); i++) {
973 if (dabr[i].enabled) {
974 brk.address = dabr[i].address;
975 brk.type = (dabr[i].enabled & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL;
978 __set_breakpoint(i, &brk);
983 set_ciabr(iabr->address);
986 static void remove_bpts(void)
993 for (i = 0; i < NBPTS; ++i, ++bp) {
994 if ((bp->enabled & (BP_TRAP|BP_CIABR)) != BP_TRAP)
996 if (mread_instr(bp->address, &instr)
997 && ppc_inst_equal(instr, ppc_inst(bpinstr))
998 && patch_instruction(
999 (u32 *)bp->address, ppc_inst_read(bp->instr)) != 0)
1000 printf("Couldn't remove breakpoint at %lx\n",
1005 static void remove_cpu_bpts(void)
1007 hw_breakpoint_disable();
1011 /* Based on uptime_proc_show(). */
1015 struct timespec64 uptime;
1017 if (setjmp(bus_error_jmp) == 0) {
1018 catch_memory_errors = 1;
1021 ktime_get_coarse_boottime_ts64(&uptime);
1022 printf("Uptime: %lu.%.2lu seconds\n", (unsigned long)uptime.tv_sec,
1023 ((unsigned long)uptime.tv_nsec / (NSEC_PER_SEC/100)));
1028 catch_memory_errors = 0;
1031 static void set_lpp_cmd(void)
1035 if (!scanhex(&lpp)) {
1036 printf("Invalid number.\n");
1039 xmon_set_pagination_lpp(lpp);
1041 /* Command interpreting routine */
1042 static char *last_cmd;
1045 cmds(struct pt_regs *excp)
1052 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1056 printf("%x:", smp_processor_id());
1057 #endif /* CONFIG_SMP */
1063 if (last_cmd == NULL)
1065 take_input(last_cmd);
1083 printf(xmon_ro_msg);
1103 prregs(excp); /* print regs */
1118 if (do_spu_cmd() == 0)
1125 if (tracing_enabled)
1129 printf(" <no input ...>\n");
1133 xmon_puts(help_string);
1153 printf(xmon_ro_msg);
1161 #if defined(CONFIG_PPC_BOOK3S_32) || defined(CONFIG_PPC_64S_HASH_MMU)
1165 #elif defined(CONFIG_44x)
1169 #elif defined(CONFIG_PPC_BOOK3E)
1178 printf("Unrecognized command: ");
1180 if (' ' < cmd && cmd <= '~')
1183 printf("\\x%x", cmd);
1185 } while (cmd != '\n');
1186 printf(" (type ? for help)\n");
1193 static int do_step(struct pt_regs *regs)
1195 regs_set_return_msr(regs, regs->msr | MSR_DE);
1196 mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
1201 * Step a single instruction.
1202 * Some instructions we emulate, others we execute with MSR_SE set.
1204 static int do_step(struct pt_regs *regs)
1209 force_enable_xmon();
1210 /* check we are in 64-bit kernel mode, translation enabled */
1211 if ((regs->msr & (MSR_64BIT|MSR_PR|MSR_IR)) == (MSR_64BIT|MSR_IR)) {
1212 if (mread_instr(regs->nip, &instr)) {
1213 stepped = emulate_step(regs, instr);
1215 printf("Couldn't single-step %s instruction\n",
1216 (IS_RFID(instr)? "rfid": "mtmsrd"));
1220 set_trap(regs, 0xd00);
1221 printf("stepped to ");
1222 xmon_print_symbol(regs->nip, " ", "\n");
1223 ppc_inst_dump(regs->nip, 1, 0);
1228 regs_set_return_msr(regs, regs->msr | MSR_SE);
1233 static void bootcmds(void)
1241 ppc_md.restart(tmp);
1242 } else if (cmd == 'h') {
1244 } else if (cmd == 'p') {
1245 do_kernel_power_off();
1250 static int xmon_switch_cpu(unsigned long cpu)
1258 while (!xmon_taken) {
1259 if (--timeout == 0) {
1260 if (test_and_set_bit(0, &xmon_taken))
1262 /* take control back */
1264 xmon_owner = smp_processor_id();
1265 printf("cpu 0x%lx didn't take control\n", cpu);
1273 static int xmon_batch_next_cpu(void)
1277 while (!cpumask_empty(&xmon_batch_cpus)) {
1278 cpu = cpumask_next_wrap(smp_processor_id(), &xmon_batch_cpus,
1279 xmon_batch_start_cpu, true);
1280 if (cpu == nr_cpumask_bits)
1282 if (xmon_batch_start_cpu == -1)
1283 xmon_batch_start_cpu = cpu;
1284 if (xmon_switch_cpu(cpu))
1286 cpumask_clear_cpu(cpu, &xmon_batch_cpus);
1290 printf("%x:mon> \n", smp_processor_id());
1294 static int batch_cmds(struct pt_regs *excp)
1298 /* simulate command entry */
1305 printf("%x:", smp_processor_id());
1307 printf("%c\n", (char)cmd);
1311 prregs(excp); /* print regs */
1321 cpumask_clear_cpu(smp_processor_id(), &xmon_batch_cpus);
1323 return xmon_batch_next_cpu();
1326 static int cpu_cmd(void)
1328 unsigned long cpu, first_cpu, last_cpu;
1332 xmon_batch = skipbl();
1334 switch (xmon_batch) {
1338 cpumask_copy(&xmon_batch_cpus, &cpus_in_xmon);
1339 if (cpumask_weight(&xmon_batch_cpus) <= 1) {
1340 printf("There are no other cpus in xmon\n");
1343 xmon_batch_start_cpu = -1;
1344 if (!xmon_batch_next_cpu())
1348 printf("c# only supports 'r', 'S' and 't' commands\n");
1356 if (!scanhex(&cpu)) {
1357 /* print cpus waiting or in xmon */
1358 printf("cpus stopped:");
1359 last_cpu = first_cpu = NR_CPUS;
1360 for_each_possible_cpu(cpu) {
1361 if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
1362 if (cpu == last_cpu + 1) {
1365 if (last_cpu != first_cpu)
1366 printf("-0x%lx", last_cpu);
1367 last_cpu = first_cpu = cpu;
1368 printf(" 0x%lx", cpu);
1372 if (last_cpu != first_cpu)
1373 printf("-0x%lx", last_cpu);
1377 /* try to switch to cpu specified */
1378 if (!cpumask_test_cpu(cpu, &cpus_in_xmon)) {
1379 printf("cpu 0x%lx isn't in xmon\n", cpu);
1381 printf("backtrace of paca[0x%lx].saved_r1 (possibly stale):\n", cpu);
1382 xmon_show_stack(paca_ptrs[cpu]->saved_r1, 0, 0);
1387 return xmon_switch_cpu(cpu);
1390 static int cpu_cmd(void)
1394 #endif /* CONFIG_SMP */
1396 static unsigned short fcstab[256] = {
1397 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
1398 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
1399 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
1400 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1401 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1402 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1403 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1404 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1405 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1406 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1407 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1408 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1409 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1410 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1411 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1412 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1413 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1414 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1415 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1416 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1417 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1418 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1419 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1420 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1421 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1422 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1423 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1424 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1425 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1426 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1427 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1428 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1431 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1440 if (!scanhex(&adrs))
1442 if (!scanhex(&ncsum))
1445 for (i = 0; i < ncsum; ++i) {
1446 if (mread(adrs+i, &v, 1) == 0) {
1447 printf("csum stopped at "REG"\n", adrs+i);
1452 printf("%x\n", fcs);
1456 * Check if this is a suitable place to put a breakpoint.
1458 static long check_bp_loc(unsigned long addr)
1463 if (!is_kernel_addr(addr)) {
1464 printf("Breakpoints may only be placed at kernel addresses\n");
1467 if (!mread_instr(addr, &instr)) {
1468 printf("Can't read instruction at address %lx\n", addr);
1471 if (!can_single_step(ppc_inst_val(instr))) {
1472 printf("Breakpoints may not be placed on instructions that can't be single stepped\n");
1478 static int find_free_data_bpt(void)
1482 for (i = 0; i < nr_wp_slots(); i++) {
1483 if (!dabr[i].enabled)
1486 printf("Couldn't find free breakpoint register\n");
1490 static void print_data_bpts(void)
1494 for (i = 0; i < nr_wp_slots(); i++) {
1495 if (!dabr[i].enabled)
1498 printf(" data "REG" [", dabr[i].address);
1499 if (dabr[i].enabled & 1)
1501 if (dabr[i].enabled & 2)
1507 static char *breakpoint_help_string =
1508 "Breakpoint command usage:\n"
1509 "b show breakpoints\n"
1510 "b <addr> [cnt] set breakpoint at given instr addr\n"
1511 "bc clear all breakpoints\n"
1512 "bc <n/addr> clear breakpoint number n or at addr\n"
1513 "bi <addr> [cnt] set hardware instr breakpoint (POWER8 only)\n"
1514 "bd <addr> [cnt] set hardware data breakpoint\n"
1528 static const char badaddr[] = "Only kernel addresses are permitted for breakpoints\n";
1530 case 'd': /* bd - hardware data breakpoint */
1532 printf(xmon_ro_msg);
1535 if (!ppc_breakpoint_available()) {
1536 printf("Hardware data breakpoint not supported on this cpu\n");
1539 i = find_free_data_bpt();
1546 else if (cmd == 'w')
1550 dabr[i].address = 0;
1551 dabr[i].enabled = 0;
1552 if (scanhex(&dabr[i].address)) {
1553 if (!is_kernel_addr(dabr[i].address)) {
1557 dabr[i].address &= ~HW_BRK_TYPE_DABR;
1558 dabr[i].enabled = mode | BP_DABR;
1561 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))
1723 #define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long))
1725 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1728 int max_to_print = 64;
1730 unsigned long newsp;
1731 unsigned long marker;
1732 struct pt_regs regs;
1734 while (max_to_print--) {
1735 if (!is_kernel_addr(sp)) {
1737 printf("SP (%lx) is in userspace\n", sp);
1741 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1742 || !mread(sp, &newsp, sizeof(unsigned long))) {
1743 printf("Couldn't read stack frame at %lx\n", sp);
1748 * For the first stack frame, try to work out if
1749 * LR and/or the saved LR value in the bottommost
1750 * stack frame are valid.
1752 if ((pc | lr) != 0) {
1753 unsigned long fnstart, fnend;
1754 unsigned long nextip;
1757 get_function_bounds(pc, &fnstart, &fnend);
1760 mread(newsp + LRSAVE_OFFSET, &nextip,
1761 sizeof(unsigned long));
1763 if (!is_kernel_addr(lr)
1764 || (fnstart <= lr && lr < fnend))
1766 } else if (lr == nextip) {
1768 } else if (is_kernel_addr(lr)
1769 && !(fnstart <= lr && lr < fnend)) {
1770 printf("[link register ] ");
1771 xmon_print_symbol(lr, " ", "\n");
1774 printf("["REG"] ", sp);
1775 xmon_print_symbol(ip, " ", " (unreliable)\n");
1780 printf("["REG"] ", sp);
1781 xmon_print_symbol(ip, " ", "\n");
1784 /* Look for "regshere" marker to see if this is
1785 an exception frame. */
1786 if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1787 && marker == STACK_FRAME_REGS_MARKER) {
1788 if (mread(sp + STACK_FRAME_OVERHEAD, ®s, sizeof(regs))
1790 printf("Couldn't read registers at %lx\n",
1791 sp + STACK_FRAME_OVERHEAD);
1794 printf("--- Exception: %lx %s at ", regs.trap,
1795 getvecname(TRAP(®s)));
1798 xmon_print_symbol(pc, " ", "\n");
1808 static void backtrace(struct pt_regs *excp)
1813 xmon_show_stack(sp, 0, 0);
1815 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1819 static void print_bug_trap(struct pt_regs *regs)
1822 const struct bug_entry *bug;
1825 if (regs->msr & MSR_PR)
1826 return; /* not in kernel */
1827 addr = regs->nip; /* address of trap instruction */
1828 if (!is_kernel_addr(addr))
1830 bug = find_bug(regs->nip);
1833 if (is_warning_bug(bug))
1836 #ifdef CONFIG_DEBUG_BUGVERBOSE
1837 printf("kernel BUG at %s:%u!\n",
1838 (char *)bug + bug->file_disp, bug->line);
1840 printf("kernel BUG at %px!\n", (void *)bug + bug->bug_addr_disp);
1842 #endif /* CONFIG_BUG */
1845 static void excprint(struct pt_regs *fp)
1850 printf("cpu 0x%x: ", smp_processor_id());
1851 #endif /* CONFIG_SMP */
1854 printf("Vector: %lx %s at [%px]\n", fp->trap, getvecname(trap), fp);
1856 xmon_print_symbol(fp->nip, ": ", "\n");
1859 xmon_print_symbol(fp->link, ": ", "\n");
1861 printf(" sp: %lx\n", fp->gpr[1]);
1862 printf(" msr: %lx\n", fp->msr);
1864 if (trap == INTERRUPT_DATA_STORAGE ||
1865 trap == INTERRUPT_DATA_SEGMENT ||
1866 trap == INTERRUPT_ALIGNMENT ||
1867 trap == INTERRUPT_MACHINE_CHECK) {
1868 printf(" dar: %lx\n", fp->dar);
1869 if (trap != INTERRUPT_DATA_SEGMENT)
1870 printf(" dsisr: %lx\n", fp->dsisr);
1873 printf(" current = 0x%px\n", current);
1875 printf(" paca = 0x%px\t irqmask: 0x%02x\t irq_happened: 0x%02x\n",
1876 local_paca, local_paca->irq_soft_mask, local_paca->irq_happened);
1879 printf(" pid = %d, comm = %s\n",
1880 current->pid, current->comm);
1883 if (trap == INTERRUPT_PROGRAM)
1886 printf(linux_banner);
1889 static void prregs(struct pt_regs *fp)
1893 struct pt_regs regs;
1895 if (scanhex(&base)) {
1896 if (setjmp(bus_error_jmp) == 0) {
1897 catch_memory_errors = 1;
1899 regs = *(struct pt_regs *)base;
1903 catch_memory_errors = 0;
1904 printf("*** Error reading registers from "REG"\n",
1908 catch_memory_errors = 0;
1913 #define R_PER_LINE 2
1915 #define R_PER_LINE 4
1918 for (n = 0; n < 32; ++n) {
1919 printf("R%.2d = "REG"%s", n, fp->gpr[n],
1920 (n % R_PER_LINE) == R_PER_LINE - 1 ? "\n" : " ");
1924 xmon_print_symbol(fp->nip, " ", "\n");
1925 if (!trap_is_syscall(fp) && cpu_has_feature(CPU_FTR_CFAR)) {
1927 xmon_print_symbol(fp->orig_gpr3, " ", "\n");
1930 xmon_print_symbol(fp->link, " ", "\n");
1931 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
1932 printf("ctr = "REG" xer = "REG" trap = %4lx\n",
1933 fp->ctr, fp->xer, fp->trap);
1935 if (trap == INTERRUPT_DATA_STORAGE ||
1936 trap == INTERRUPT_DATA_SEGMENT ||
1937 trap == INTERRUPT_ALIGNMENT)
1938 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1941 static void cacheflush(void)
1944 unsigned long nflush;
1949 scanhex((void *)&adrs);
1954 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1955 if (setjmp(bus_error_jmp) == 0) {
1956 catch_memory_errors = 1;
1959 if (cmd != 'i' || IS_ENABLED(CONFIG_PPC_BOOK3S_64)) {
1960 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1961 cflush((void *) adrs);
1963 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1964 cinval((void *) adrs);
1967 /* wait a little while to see if we get a machine check */
1970 catch_memory_errors = 0;
1973 extern unsigned long xmon_mfspr(int spr, unsigned long default_value);
1974 extern void xmon_mtspr(int spr, unsigned long value);
1977 read_spr(int n, unsigned long *vp)
1979 unsigned long ret = -1UL;
1982 if (setjmp(bus_error_jmp) == 0) {
1983 catch_spr_faults = 1;
1986 ret = xmon_mfspr(n, *vp);
1992 catch_spr_faults = 0;
1998 write_spr(int n, unsigned long val)
2001 printf(xmon_ro_msg);
2005 if (setjmp(bus_error_jmp) == 0) {
2006 catch_spr_faults = 1;
2013 printf("SPR 0x%03x (%4d) Faulted during write\n", n, n);
2015 catch_spr_faults = 0;
2018 static void dump_206_sprs(void)
2021 if (!cpu_has_feature(CPU_FTR_ARCH_206))
2024 /* Actually some of these pre-date 2.06, but whatever */
2026 printf("srr0 = %.16lx srr1 = %.16lx dsisr = %.8lx\n",
2027 mfspr(SPRN_SRR0), mfspr(SPRN_SRR1), mfspr(SPRN_DSISR));
2028 printf("dscr = %.16lx ppr = %.16lx pir = %.8lx\n",
2029 mfspr(SPRN_DSCR), mfspr(SPRN_PPR), mfspr(SPRN_PIR));
2030 printf("amr = %.16lx uamor = %.16lx\n",
2031 mfspr(SPRN_AMR), mfspr(SPRN_UAMOR));
2033 if (!(mfmsr() & MSR_HV))
2036 printf("sdr1 = %.16lx hdar = %.16lx hdsisr = %.8lx\n",
2037 mfspr(SPRN_SDR1), mfspr(SPRN_HDAR), mfspr(SPRN_HDSISR));
2038 printf("hsrr0 = %.16lx hsrr1 = %.16lx hdec = %.16lx\n",
2039 mfspr(SPRN_HSRR0), mfspr(SPRN_HSRR1), mfspr(SPRN_HDEC));
2040 printf("lpcr = %.16lx pcr = %.16lx lpidr = %.8lx\n",
2041 mfspr(SPRN_LPCR), mfspr(SPRN_PCR), mfspr(SPRN_LPID));
2042 printf("hsprg0 = %.16lx hsprg1 = %.16lx amor = %.16lx\n",
2043 mfspr(SPRN_HSPRG0), mfspr(SPRN_HSPRG1), mfspr(SPRN_AMOR));
2044 printf("dabr = %.16lx dabrx = %.16lx\n",
2045 mfspr(SPRN_DABR), mfspr(SPRN_DABRX));
2049 static void dump_207_sprs(void)
2054 if (!cpu_has_feature(CPU_FTR_ARCH_207S))
2057 printf("dpdes = %.16lx tir = %.16lx cir = %.8lx\n",
2058 mfspr(SPRN_DPDES), mfspr(SPRN_TIR), mfspr(SPRN_CIR));
2060 printf("fscr = %.16lx tar = %.16lx pspb = %.8lx\n",
2061 mfspr(SPRN_FSCR), mfspr(SPRN_TAR), mfspr(SPRN_PSPB));
2065 /* Only if TM has been enabled in the kernel */
2066 printf("tfhar = %.16lx tfiar = %.16lx texasr = %.16lx\n",
2067 mfspr(SPRN_TFHAR), mfspr(SPRN_TFIAR),
2068 mfspr(SPRN_TEXASR));
2071 printf("mmcr0 = %.16lx mmcr1 = %.16lx mmcr2 = %.16lx\n",
2072 mfspr(SPRN_MMCR0), mfspr(SPRN_MMCR1), mfspr(SPRN_MMCR2));
2073 printf("pmc1 = %.8lx pmc2 = %.8lx pmc3 = %.8lx pmc4 = %.8lx\n",
2074 mfspr(SPRN_PMC1), mfspr(SPRN_PMC2),
2075 mfspr(SPRN_PMC3), mfspr(SPRN_PMC4));
2076 printf("mmcra = %.16lx siar = %.16lx pmc5 = %.8lx\n",
2077 mfspr(SPRN_MMCRA), mfspr(SPRN_SIAR), mfspr(SPRN_PMC5));
2078 printf("sdar = %.16lx sier = %.16lx pmc6 = %.8lx\n",
2079 mfspr(SPRN_SDAR), mfspr(SPRN_SIER), mfspr(SPRN_PMC6));
2080 printf("ebbhr = %.16lx ebbrr = %.16lx bescr = %.16lx\n",
2081 mfspr(SPRN_EBBHR), mfspr(SPRN_EBBRR), mfspr(SPRN_BESCR));
2082 printf("iamr = %.16lx\n", mfspr(SPRN_IAMR));
2084 if (!(msr & MSR_HV))
2087 printf("hfscr = %.16lx dhdes = %.16lx rpr = %.16lx\n",
2088 mfspr(SPRN_HFSCR), mfspr(SPRN_DHDES), mfspr(SPRN_RPR));
2089 printf("dawr0 = %.16lx dawrx0 = %.16lx\n",
2090 mfspr(SPRN_DAWR0), mfspr(SPRN_DAWRX0));
2091 if (nr_wp_slots() > 1) {
2092 printf("dawr1 = %.16lx dawrx1 = %.16lx\n",
2093 mfspr(SPRN_DAWR1), mfspr(SPRN_DAWRX1));
2095 printf("ciabr = %.16lx\n", mfspr(SPRN_CIABR));
2099 static void dump_300_sprs(void)
2102 bool hv = mfmsr() & MSR_HV;
2104 if (!cpu_has_feature(CPU_FTR_ARCH_300))
2107 if (cpu_has_feature(CPU_FTR_P9_TIDR)) {
2108 printf("pidr = %.16lx tidr = %.16lx\n",
2109 mfspr(SPRN_PID), mfspr(SPRN_TIDR));
2111 printf("pidr = %.16lx\n",
2115 printf("psscr = %.16lx\n",
2116 hv ? mfspr(SPRN_PSSCR) : mfspr(SPRN_PSSCR_PR));
2121 printf("ptcr = %.16lx asdr = %.16lx\n",
2122 mfspr(SPRN_PTCR), mfspr(SPRN_ASDR));
2126 static void dump_310_sprs(void)
2129 if (!cpu_has_feature(CPU_FTR_ARCH_31))
2132 printf("mmcr3 = %.16lx, sier2 = %.16lx, sier3 = %.16lx\n",
2133 mfspr(SPRN_MMCR3), mfspr(SPRN_SIER2), mfspr(SPRN_SIER3));
2138 static void dump_one_spr(int spr, bool show_unimplemented)
2143 if (!read_spr(spr, &val)) {
2144 printf("SPR 0x%03x (%4d) Faulted during read\n", spr, spr);
2148 if (val == 0xdeadbeef) {
2149 /* Looks like read was a nop, confirm */
2151 if (!read_spr(spr, &val)) {
2152 printf("SPR 0x%03x (%4d) Faulted during read\n", spr, spr);
2156 if (val == 0x0badcafe) {
2157 if (show_unimplemented)
2158 printf("SPR 0x%03x (%4d) Unimplemented\n", spr, spr);
2163 printf("SPR 0x%03x (%4d) = 0x%lx\n", spr, spr, val);
2166 static void super_regs(void)
2168 static unsigned long regno;
2176 unsigned long sp, toc;
2177 asm("mr %0,1" : "=r" (sp) :);
2178 asm("mr %0,2" : "=r" (toc) :);
2180 printf("msr = "REG" sprg0 = "REG"\n",
2181 mfmsr(), mfspr(SPRN_SPRG0));
2182 printf("pvr = "REG" sprg1 = "REG"\n",
2183 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
2184 printf("dec = "REG" sprg2 = "REG"\n",
2185 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
2186 printf("sp = "REG" sprg3 = "REG"\n", sp, mfspr(SPRN_SPRG3));
2187 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
2200 read_spr(regno, &val);
2202 write_spr(regno, val);
2203 dump_one_spr(regno, true);
2208 dump_one_spr(regno, true);
2212 for (spr = 1; spr < 1024; ++spr)
2213 dump_one_spr(spr, false);
2221 * Stuff for reading and writing memory safely
2224 mread(unsigned long adrs, void *buf, int size)
2230 if (setjmp(bus_error_jmp) == 0) {
2231 catch_memory_errors = 1;
2237 *(u16 *)q = *(u16 *)p;
2240 *(u32 *)q = *(u32 *)p;
2243 *(u64 *)q = *(u64 *)p;
2246 for( ; n < size; ++n) {
2252 /* wait a little while to see if we get a machine check */
2256 catch_memory_errors = 0;
2261 mwrite(unsigned long adrs, void *buf, int size)
2269 printf(xmon_ro_msg);
2273 if (setjmp(bus_error_jmp) == 0) {
2274 catch_memory_errors = 1;
2280 *(u16 *)p = *(u16 *)q;
2283 *(u32 *)p = *(u32 *)q;
2286 *(u64 *)p = *(u64 *)q;
2289 for ( ; n < size; ++n) {
2295 /* wait a little while to see if we get a machine check */
2299 printf("*** Error writing address "REG"\n", adrs + n);
2301 catch_memory_errors = 0;
2306 mread_instr(unsigned long adrs, ppc_inst_t *instr)
2311 if (setjmp(bus_error_jmp) == 0) {
2312 catch_memory_errors = 1;
2314 *instr = ppc_inst_read((u32 *)adrs);
2316 /* wait a little while to see if we get a machine check */
2318 n = ppc_inst_len(*instr);
2320 catch_memory_errors = 0;
2324 static int fault_type;
2325 static int fault_except;
2326 static char *fault_chars[] = { "--", "**", "##" };
2328 static int handle_fault(struct pt_regs *regs)
2330 fault_except = TRAP(regs);
2331 switch (TRAP(regs)) {
2343 longjmp(bus_error_jmp, 1);
2348 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
2351 byterev(unsigned char *val, int size)
2357 SWAP(val[0], val[1], t);
2360 SWAP(val[0], val[3], t);
2361 SWAP(val[1], val[2], t);
2363 case 8: /* is there really any use for this? */
2364 SWAP(val[0], val[7], t);
2365 SWAP(val[1], val[6], t);
2366 SWAP(val[2], val[5], t);
2367 SWAP(val[3], val[4], t);
2375 static char *memex_help_string =
2376 "Memory examine command usage:\n"
2377 "m [addr] [flags] examine/change memory\n"
2378 " addr is optional. will start where left off.\n"
2379 " flags may include chars from this set:\n"
2380 " b modify by bytes (default)\n"
2381 " w modify by words (2 byte)\n"
2382 " l modify by longs (4 byte)\n"
2383 " d modify by doubleword (8 byte)\n"
2384 " r toggle reverse byte order mode\n"
2385 " n do not read memory (for i/o spaces)\n"
2386 " . ok to read (default)\n"
2387 "NOTE: flags are saved as defaults\n"
2390 static char *memex_subcmd_help_string =
2391 "Memory examine subcommands:\n"
2392 " hexval write this val to current location\n"
2393 " 'string' write chars from string to this location\n"
2394 " ' increment address\n"
2395 " ^ decrement address\n"
2396 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
2397 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
2398 " ` clear no-read flag\n"
2399 " ; stay at this addr\n"
2400 " v change to byte mode\n"
2401 " w change to word (2 byte) mode\n"
2402 " l change to long (4 byte) mode\n"
2403 " u change to doubleword (8 byte) mode\n"
2404 " m addr change current addr\n"
2405 " n toggle no-read flag\n"
2406 " r toggle byte reverse flag\n"
2407 " < count back up count bytes\n"
2408 " > count skip forward count bytes\n"
2409 " x exit this mode\n"
2415 int cmd, inc, i, nslash;
2417 unsigned char val[16];
2419 scanhex((void *)&adrs);
2422 printf(memex_help_string);
2428 while ((cmd = skipbl()) != '\n') {
2430 case 'b': size = 1; break;
2431 case 'w': size = 2; break;
2432 case 'l': size = 4; break;
2433 case 'd': size = 8; break;
2434 case 'r': brev = !brev; break;
2435 case 'n': mnoread = 1; break;
2436 case '.': mnoread = 0; break;
2445 n = mread(adrs, val, size);
2446 printf(REG"%c", adrs, brev? 'r': ' ');
2451 for (i = 0; i < n; ++i)
2452 printf("%.2x", val[i]);
2453 for (; i < size; ++i)
2454 printf("%s", fault_chars[fault_type]);
2461 for (i = 0; i < size; ++i)
2462 val[i] = n >> (i * 8);
2465 mwrite(adrs, val, size);
2478 else if( n == '\'' )
2480 for (i = 0; i < size; ++i)
2481 val[i] = n >> (i * 8);
2484 mwrite(adrs, val, size);
2520 adrs -= 1 << nslash;
2524 adrs += 1 << nslash;
2528 adrs += 1 << -nslash;
2532 adrs -= 1 << -nslash;
2535 scanhex((void *)&adrs);
2554 printf(memex_subcmd_help_string);
2569 case 'n': c = '\n'; break;
2570 case 'r': c = '\r'; break;
2571 case 'b': c = '\b'; break;
2572 case 't': c = '\t'; break;
2577 static void xmon_rawdump (unsigned long adrs, long ndump)
2580 unsigned char temp[16];
2582 for (n = ndump; n > 0;) {
2584 nr = mread(adrs, temp, r);
2586 for (m = 0; m < r; ++m) {
2588 printf("%.2x", temp[m]);
2590 printf("%s", fault_chars[fault_type]);
2599 static void dump_tracing(void)
2605 ftrace_dump(DUMP_ORIG);
2607 ftrace_dump(DUMP_ALL);
2611 static void dump_one_paca(int cpu)
2613 struct paca_struct *p;
2614 #ifdef CONFIG_PPC_64S_HASH_MMU
2618 if (setjmp(bus_error_jmp) != 0) {
2619 printf("*** Error dumping paca for cpu 0x%x!\n", cpu);
2623 catch_memory_errors = 1;
2628 printf("paca for cpu 0x%x @ %px:\n", cpu, p);
2630 printf(" %-*s = %s\n", 25, "possible", cpu_possible(cpu) ? "yes" : "no");
2631 printf(" %-*s = %s\n", 25, "present", cpu_present(cpu) ? "yes" : "no");
2632 printf(" %-*s = %s\n", 25, "online", cpu_online(cpu) ? "yes" : "no");
2634 #define DUMP(paca, name, format) \
2635 printf(" %-*s = "format"\t(0x%lx)\n", 25, #name, 18, paca->name, \
2636 offsetof(struct paca_struct, name));
2638 DUMP(p, lock_token, "%#-*x");
2639 DUMP(p, paca_index, "%#-*x");
2640 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
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
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" %s", adr, ppc_inst_as_str(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 *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 (pte_none(*ptep)) {
3381 printf("no valid PTE\n");
3385 format_pte(ptep, pte_val(*ptep));
3389 catch_memory_errors = 0;
3392 static void show_pte(unsigned long addr)
3394 printf("show_pte not yet implemented\n");
3396 #endif /* CONFIG_PPC_BOOK3S_64 */
3398 static void show_tasks(void)
3401 struct task_struct *volatile tsk = NULL;
3403 printf(" task_struct ->thread.ksp ->thread.regs PID PPID S P CMD\n");
3406 tsk = (struct task_struct *)tskv;
3408 if (setjmp(bus_error_jmp) != 0) {
3409 catch_memory_errors = 0;
3410 printf("*** Error dumping task %px\n", tsk);
3414 catch_memory_errors = 1;
3420 for_each_process(tsk)
3425 catch_memory_errors = 0;
3428 static void proccall(void)
3430 unsigned long args[8];
3433 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
3434 unsigned long, unsigned long, unsigned long,
3435 unsigned long, unsigned long, unsigned long);
3438 if (!scanhex(&adrs))
3442 for (i = 0; i < 8; ++i)
3444 for (i = 0; i < 8; ++i) {
3445 if (!scanhex(&args[i]) || termch == '\n')
3449 func = (callfunc_t) adrs;
3451 if (setjmp(bus_error_jmp) == 0) {
3452 catch_memory_errors = 1;
3454 ret = func(args[0], args[1], args[2], args[3],
3455 args[4], args[5], args[6], args[7]);
3457 printf("return value is 0x%lx\n", ret);
3459 printf("*** %x exception occurred\n", fault_except);
3461 catch_memory_errors = 0;
3464 /* Input scanning routines */
3475 while( c == ' ' || c == '\t' )
3481 static const char *regnames[N_PTREGS] = {
3482 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
3483 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
3484 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
3485 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
3486 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
3492 "trap", "dar", "dsisr", "res"
3496 scanhex(unsigned long *vp)
3503 /* parse register name */
3507 for (i = 0; i < sizeof(regname) - 1; ++i) {
3516 i = match_string(regnames, N_PTREGS, regname);
3518 printf("invalid register name '%%%s'\n", regname);
3521 if (xmon_regs == NULL) {
3522 printf("regs not available\n");
3525 *vp = ((unsigned long *)xmon_regs)[i];
3529 /* skip leading "0x" if any */
3543 } else if (c == '$') {
3545 for (i=0; i<63; i++) {
3547 if (isspace(c) || c == '\0') {
3555 if (setjmp(bus_error_jmp) == 0) {
3556 catch_memory_errors = 1;
3558 *vp = kallsyms_lookup_name(tmpstr);
3561 catch_memory_errors = 0;
3563 printf("unknown symbol '%s'\n", tmpstr);
3596 static int hexdigit(int c)
3598 if( '0' <= c && c <= '9' )
3600 if( 'A' <= c && c <= 'F' )
3601 return c - ('A' - 10);
3602 if( 'a' <= c && c <= 'f' )
3603 return c - ('a' - 10);
3608 getstring(char *s, int size)
3624 } while( c != ' ' && c != '\t' && c != '\n' );
3629 static char line[256];
3630 static char *lineptr;
3641 if (lineptr == NULL || *lineptr == 0) {
3642 if (xmon_gets(line, sizeof(line)) == NULL) {
3652 take_input(char *str)
3661 int type = inchar();
3662 unsigned long addr, cpu;
3663 void __percpu *ptr = NULL;
3664 static char tmp[64];
3669 xmon_print_symbol(addr, ": ", "\n");
3674 if (setjmp(bus_error_jmp) == 0) {
3675 catch_memory_errors = 1;
3677 addr = kallsyms_lookup_name(tmp);
3679 printf("%s: %lx\n", tmp, addr);
3681 printf("Symbol '%s' not found.\n", tmp);
3684 catch_memory_errors = 0;
3689 if (setjmp(bus_error_jmp) == 0) {
3690 catch_memory_errors = 1;
3692 ptr = (void __percpu *)kallsyms_lookup_name(tmp);
3697 ptr >= (void __percpu *)__per_cpu_start &&
3698 ptr < (void __percpu *)__per_cpu_end)
3700 if (scanhex(&cpu) && cpu < num_possible_cpus()) {
3701 addr = (unsigned long)per_cpu_ptr(ptr, cpu);
3703 cpu = raw_smp_processor_id();
3704 addr = (unsigned long)this_cpu_ptr(ptr);
3707 printf("%s for cpu 0x%lx: %lx\n", tmp, cpu, addr);
3709 printf("Percpu symbol '%s' not found.\n", tmp);
3712 catch_memory_errors = 0;
3719 /* Print an address in numeric and symbolic form (if possible) */
3720 static void xmon_print_symbol(unsigned long address, const char *mid,
3724 const char *volatile name = NULL;
3725 unsigned long offset, size;
3727 printf(REG, address);
3728 if (setjmp(bus_error_jmp) == 0) {
3729 catch_memory_errors = 1;
3731 name = kallsyms_lookup(address, &size, &offset, &modname,
3734 /* wait a little while to see if we get a machine check */
3738 catch_memory_errors = 0;
3741 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
3743 printf(" [%s]", modname);
3745 printf("%s", after);
3748 #ifdef CONFIG_PPC_64S_HASH_MMU
3749 void dump_segments(void)
3752 unsigned long esid,vsid;
3755 printf("SLB contents of cpu 0x%x\n", smp_processor_id());
3757 for (i = 0; i < mmu_slb_size; i++) {
3758 asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i));
3759 asm volatile("slbmfev %0,%1" : "=r" (vsid) : "r" (i));
3764 printf("%02d %016lx %016lx", i, esid, vsid);
3766 if (!(esid & SLB_ESID_V)) {
3771 llp = vsid & SLB_VSID_LLP;
3772 if (vsid & SLB_VSID_B_1T) {
3773 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
3775 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T,
3778 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
3780 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT,
3787 #ifdef CONFIG_PPC_BOOK3S_32
3788 void dump_segments(void)
3793 for (i = 0; i < 16; ++i)
3794 printf(" %x", mfsr(i << 28));
3800 static void dump_tlb_44x(void)
3804 for (i = 0; i < PPC44x_TLB_SIZE; i++) {
3805 unsigned long w0,w1,w2;
3806 asm volatile("tlbre %0,%1,0" : "=r" (w0) : "r" (i));
3807 asm volatile("tlbre %0,%1,1" : "=r" (w1) : "r" (i));
3808 asm volatile("tlbre %0,%1,2" : "=r" (w2) : "r" (i));
3809 printf("[%02x] %08lx %08lx %08lx ", i, w0, w1, w2);
3810 if (w0 & PPC44x_TLB_VALID) {
3811 printf("V %08lx -> %01lx%08lx %c%c%c%c%c",
3812 w0 & PPC44x_TLB_EPN_MASK,
3813 w1 & PPC44x_TLB_ERPN_MASK,
3814 w1 & PPC44x_TLB_RPN_MASK,
3815 (w2 & PPC44x_TLB_W) ? 'W' : 'w',
3816 (w2 & PPC44x_TLB_I) ? 'I' : 'i',
3817 (w2 & PPC44x_TLB_M) ? 'M' : 'm',
3818 (w2 & PPC44x_TLB_G) ? 'G' : 'g',
3819 (w2 & PPC44x_TLB_E) ? 'E' : 'e');
3824 #endif /* CONFIG_44x */
3826 #ifdef CONFIG_PPC_BOOK3E
3827 static void dump_tlb_book3e(void)
3829 u32 mmucfg, pidmask, lpidmask;
3831 int i, tlb, ntlbs, pidsz, lpidsz, rasz, lrat = 0;
3833 static const char *pgsz_names[] = {
3868 /* Gather some infos about the MMU */
3869 mmucfg = mfspr(SPRN_MMUCFG);
3870 mmu_version = (mmucfg & 3) + 1;
3871 ntlbs = ((mmucfg >> 2) & 3) + 1;
3872 pidsz = ((mmucfg >> 6) & 0x1f) + 1;
3873 lpidsz = (mmucfg >> 24) & 0xf;
3874 rasz = (mmucfg >> 16) & 0x7f;
3875 if ((mmu_version > 1) && (mmucfg & 0x10000))
3877 printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n",
3878 mmu_version, ntlbs, pidsz, lpidsz, rasz);
3879 pidmask = (1ul << pidsz) - 1;
3880 lpidmask = (1ul << lpidsz) - 1;
3881 ramask = (1ull << rasz) - 1;
3883 for (tlb = 0; tlb < ntlbs; tlb++) {
3885 int nent, assoc, new_cc = 1;
3886 printf("TLB %d:\n------\n", tlb);
3889 tlbcfg = mfspr(SPRN_TLB0CFG);
3892 tlbcfg = mfspr(SPRN_TLB1CFG);
3895 tlbcfg = mfspr(SPRN_TLB2CFG);
3898 tlbcfg = mfspr(SPRN_TLB3CFG);
3901 printf("Unsupported TLB number !\n");
3904 nent = tlbcfg & 0xfff;
3905 assoc = (tlbcfg >> 24) & 0xff;
3906 for (i = 0; i < nent; i++) {
3907 u32 mas0 = MAS0_TLBSEL(tlb);
3908 u32 mas1 = MAS1_TSIZE(BOOK3E_PAGESZ_4K);
3911 int esel = i, cc = i;
3919 mas0 |= MAS0_ESEL(esel);
3920 mtspr(SPRN_MAS0, mas0);
3921 mtspr(SPRN_MAS1, mas1);
3922 mtspr(SPRN_MAS2, mas2);
3923 asm volatile("tlbre 0,0,0" : : : "memory");
3924 mas1 = mfspr(SPRN_MAS1);
3925 mas2 = mfspr(SPRN_MAS2);
3926 mas7_mas3 = mfspr(SPRN_MAS7_MAS3);
3927 if (assoc && (i % assoc) == 0)
3929 if (!(mas1 & MAS1_VALID))
3932 printf("%04x- ", i);
3934 printf("%04x-%c", cc, 'A' + esel);
3936 printf(" |%c", 'A' + esel);
3938 printf(" %016llx %04x %s %c%c AS%c",
3940 (mas1 >> 16) & 0x3fff,
3941 pgsz_names[(mas1 >> 7) & 0x1f],
3942 mas1 & MAS1_IND ? 'I' : ' ',
3943 mas1 & MAS1_IPROT ? 'P' : ' ',
3944 mas1 & MAS1_TS ? '1' : '0');
3945 printf(" %c%c%c%c%c%c%c",
3946 mas2 & MAS2_X0 ? 'a' : ' ',
3947 mas2 & MAS2_X1 ? 'v' : ' ',
3948 mas2 & MAS2_W ? 'w' : ' ',
3949 mas2 & MAS2_I ? 'i' : ' ',
3950 mas2 & MAS2_M ? 'm' : ' ',
3951 mas2 & MAS2_G ? 'g' : ' ',
3952 mas2 & MAS2_E ? 'e' : ' ');
3953 printf(" %016llx", mas7_mas3 & ramask & ~0x7ffull);
3954 if (mas1 & MAS1_IND)
3956 pgsz_names[(mas7_mas3 >> 1) & 0x1f]);
3958 printf(" U%c%c%c S%c%c%c\n",
3959 mas7_mas3 & MAS3_UX ? 'x' : ' ',
3960 mas7_mas3 & MAS3_UW ? 'w' : ' ',
3961 mas7_mas3 & MAS3_UR ? 'r' : ' ',
3962 mas7_mas3 & MAS3_SX ? 'x' : ' ',
3963 mas7_mas3 & MAS3_SW ? 'w' : ' ',
3964 mas7_mas3 & MAS3_SR ? 'r' : ' ');
3968 #endif /* CONFIG_PPC_BOOK3E */
3970 static void xmon_init(int enable)
3974 __debugger_ipi = xmon_ipi;
3975 __debugger_bpt = xmon_bpt;
3976 __debugger_sstep = xmon_sstep;
3977 __debugger_iabr_match = xmon_iabr_match;
3978 __debugger_break_match = xmon_break_match;
3979 __debugger_fault_handler = xmon_fault_handler;
3981 #ifdef CONFIG_PPC_PSERIES
3983 * Get the token here to avoid trying to get a lock
3984 * during the crash, causing a deadlock.
3986 set_indicator_token = rtas_token("set-indicator");
3990 __debugger_ipi = NULL;
3991 __debugger_bpt = NULL;
3992 __debugger_sstep = NULL;
3993 __debugger_iabr_match = NULL;
3994 __debugger_break_match = NULL;
3995 __debugger_fault_handler = NULL;
3999 #ifdef CONFIG_MAGIC_SYSRQ
4000 static void sysrq_handle_xmon(int key)
4002 if (xmon_is_locked_down()) {
4007 /* ensure xmon is enabled */
4009 debugger(get_irq_regs());
4014 static const struct sysrq_key_op sysrq_xmon_op = {
4015 .handler = sysrq_handle_xmon,
4016 .help_msg = "xmon(x)",
4017 .action_msg = "Entering xmon",
4020 static int __init setup_xmon_sysrq(void)
4022 register_sysrq_key('x', &sysrq_xmon_op);
4025 device_initcall(setup_xmon_sysrq);
4026 #endif /* CONFIG_MAGIC_SYSRQ */
4028 static void clear_all_bpt(void)
4032 /* clear/unpatch all breakpoints */
4036 /* Disable all breakpoints */
4037 for (i = 0; i < NBPTS; ++i)
4038 bpts[i].enabled = 0;
4040 /* Clear any data or iabr breakpoints */
4042 for (i = 0; i < nr_wp_slots(); i++)
4043 dabr[i].enabled = 0;
4046 #ifdef CONFIG_DEBUG_FS
4047 static int xmon_dbgfs_set(void *data, u64 val)
4052 /* make sure all breakpoints removed when disabling */
4056 printf("xmon: All breakpoints cleared\n");
4057 release_output_lock();
4063 static int xmon_dbgfs_get(void *data, u64 *val)
4069 DEFINE_SIMPLE_ATTRIBUTE(xmon_dbgfs_ops, xmon_dbgfs_get,
4070 xmon_dbgfs_set, "%llu\n");
4072 static int __init setup_xmon_dbgfs(void)
4074 debugfs_create_file("xmon", 0600, arch_debugfs_dir, NULL,
4078 device_initcall(setup_xmon_dbgfs);
4079 #endif /* CONFIG_DEBUG_FS */
4081 static int xmon_early __initdata;
4083 static int __init early_parse_xmon(char *p)
4085 if (xmon_is_locked_down()) {
4089 } else if (!p || strncmp(p, "early", 5) == 0) {
4090 /* just "xmon" is equivalent to "xmon=early" */
4094 } else if (strncmp(p, "on", 2) == 0) {
4097 } else if (strncmp(p, "rw", 2) == 0) {
4101 } else if (strncmp(p, "ro", 2) == 0) {
4105 } else if (strncmp(p, "off", 3) == 0)
4112 early_param("xmon", early_parse_xmon);
4114 void __init xmon_setup(void)
4122 #ifdef CONFIG_SPU_BASE
4126 u64 saved_mfc_sr1_RW;
4127 u32 saved_spu_runcntl_RW;
4128 unsigned long dump_addr;
4132 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
4134 static struct spu_info spu_info[XMON_NUM_SPUS];
4136 void __init xmon_register_spus(struct list_head *list)
4140 list_for_each_entry(spu, list, full_list) {
4141 if (spu->number >= XMON_NUM_SPUS) {
4146 spu_info[spu->number].spu = spu;
4147 spu_info[spu->number].stopped_ok = 0;
4148 spu_info[spu->number].dump_addr = (unsigned long)
4149 spu_info[spu->number].spu->local_store;
4153 static void stop_spus(void)
4159 for (i = 0; i < XMON_NUM_SPUS; i++) {
4160 if (!spu_info[i].spu)
4163 if (setjmp(bus_error_jmp) == 0) {
4164 catch_memory_errors = 1;
4167 spu = spu_info[i].spu;
4169 spu_info[i].saved_spu_runcntl_RW =
4170 in_be32(&spu->problem->spu_runcntl_RW);
4172 tmp = spu_mfc_sr1_get(spu);
4173 spu_info[i].saved_mfc_sr1_RW = tmp;
4175 tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
4176 spu_mfc_sr1_set(spu, tmp);
4181 spu_info[i].stopped_ok = 1;
4183 printf("Stopped spu %.2d (was %s)\n", i,
4184 spu_info[i].saved_spu_runcntl_RW ?
4185 "running" : "stopped");
4187 catch_memory_errors = 0;
4188 printf("*** Error stopping spu %.2d\n", i);
4190 catch_memory_errors = 0;
4194 static void restart_spus(void)
4199 for (i = 0; i < XMON_NUM_SPUS; i++) {
4200 if (!spu_info[i].spu)
4203 if (!spu_info[i].stopped_ok) {
4204 printf("*** Error, spu %d was not successfully stopped"
4205 ", not restarting\n", i);
4209 if (setjmp(bus_error_jmp) == 0) {
4210 catch_memory_errors = 1;
4213 spu = spu_info[i].spu;
4214 spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
4215 out_be32(&spu->problem->spu_runcntl_RW,
4216 spu_info[i].saved_spu_runcntl_RW);
4221 printf("Restarted spu %.2d\n", i);
4223 catch_memory_errors = 0;
4224 printf("*** Error restarting spu %.2d\n", i);
4226 catch_memory_errors = 0;
4230 #define DUMP_WIDTH 23
4231 #define DUMP_VALUE(format, field, value) \
4233 if (setjmp(bus_error_jmp) == 0) { \
4234 catch_memory_errors = 1; \
4236 printf(" %-*s = "format"\n", DUMP_WIDTH, \
4241 catch_memory_errors = 0; \
4242 printf(" %-*s = *** Error reading field.\n", \
4243 DUMP_WIDTH, #field); \
4245 catch_memory_errors = 0; \
4248 #define DUMP_FIELD(obj, format, field) \
4249 DUMP_VALUE(format, field, obj->field)
4251 static void dump_spu_fields(struct spu *spu)
4253 printf("Dumping spu fields at address %p:\n", spu);
4255 DUMP_FIELD(spu, "0x%x", number);
4256 DUMP_FIELD(spu, "%s", name);
4257 DUMP_FIELD(spu, "0x%lx", local_store_phys);
4258 DUMP_FIELD(spu, "0x%p", local_store);
4259 DUMP_FIELD(spu, "0x%lx", ls_size);
4260 DUMP_FIELD(spu, "0x%x", node);
4261 DUMP_FIELD(spu, "0x%lx", flags);
4262 DUMP_FIELD(spu, "%llu", class_0_pending);
4263 DUMP_FIELD(spu, "0x%llx", class_0_dar);
4264 DUMP_FIELD(spu, "0x%llx", class_1_dar);
4265 DUMP_FIELD(spu, "0x%llx", class_1_dsisr);
4266 DUMP_FIELD(spu, "0x%x", irqs[0]);
4267 DUMP_FIELD(spu, "0x%x", irqs[1]);
4268 DUMP_FIELD(spu, "0x%x", irqs[2]);
4269 DUMP_FIELD(spu, "0x%x", slb_replace);
4270 DUMP_FIELD(spu, "%d", pid);
4271 DUMP_FIELD(spu, "0x%p", mm);
4272 DUMP_FIELD(spu, "0x%p", ctx);
4273 DUMP_FIELD(spu, "0x%p", rq);
4274 DUMP_FIELD(spu, "0x%llx", timestamp);
4275 DUMP_FIELD(spu, "0x%lx", problem_phys);
4276 DUMP_FIELD(spu, "0x%p", problem);
4277 DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
4278 in_be32(&spu->problem->spu_runcntl_RW));
4279 DUMP_VALUE("0x%x", problem->spu_status_R,
4280 in_be32(&spu->problem->spu_status_R));
4281 DUMP_VALUE("0x%x", problem->spu_npc_RW,
4282 in_be32(&spu->problem->spu_npc_RW));
4283 DUMP_FIELD(spu, "0x%p", priv2);
4284 DUMP_FIELD(spu, "0x%p", pdata);
4287 static int spu_inst_dump(unsigned long adr, long count, int praddr)
4289 return generic_inst_dump(adr, count, praddr, print_insn_spu);
4292 static void dump_spu_ls(unsigned long num, int subcmd)
4294 unsigned long offset, addr, ls_addr;
4296 if (setjmp(bus_error_jmp) == 0) {
4297 catch_memory_errors = 1;
4299 ls_addr = (unsigned long)spu_info[num].spu->local_store;
4303 catch_memory_errors = 0;
4304 printf("*** Error: accessing spu info for spu %ld\n", num);
4307 catch_memory_errors = 0;
4309 if (scanhex(&offset))
4310 addr = ls_addr + offset;
4312 addr = spu_info[num].dump_addr;
4314 if (addr >= ls_addr + LS_SIZE) {
4315 printf("*** Error: address outside of local store\n");
4321 addr += spu_inst_dump(addr, 16, 1);
4331 spu_info[num].dump_addr = addr;
4334 static int do_spu_cmd(void)
4336 static unsigned long num = 0;
4337 int cmd, subcmd = 0;
4349 if (isxdigit(subcmd) || subcmd == '\n')
4354 if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
4355 printf("*** Error: invalid spu number\n");
4361 dump_spu_fields(spu_info[num].spu);
4364 dump_spu_ls(num, subcmd);
4375 #else /* ! CONFIG_SPU_BASE */
4376 static int do_spu_cmd(void)