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();
647 cmd = batch_cmds(regs);
648 if (!locked_down && cmd)
650 if (locked_down || cmd != 0) {
658 /* have switched to some other cpu */
663 cpumask_clear_cpu(cpu, &cpus_in_xmon);
664 xmon_fault_jmp[cpu] = NULL;
666 /* UP is simple... */
668 printf("Exception %lx %s in xmon, returning to main loop\n",
669 regs->trap, getvecname(TRAP(regs)));
670 longjmp(xmon_fault_jmp[0], 1);
672 if (setjmp(recurse_jmp) == 0) {
673 xmon_fault_jmp[0] = recurse_jmp;
677 bp = at_breakpoint(regs->nip);
679 printf("Stopped at breakpoint %tx (", BP_NUM(bp));
680 xmon_print_symbol(regs->nip, " ", ")\n");
682 if (regs_is_unrecoverable(regs))
683 printf("WARNING: exception is not recoverable, "
686 disable_surveillance();
688 /* for breakpoint or single step, print current insn */
689 if (bp || TRAP(regs) == INTERRUPT_TRACE)
690 ppc_inst_dump(regs->nip, 1, 0);
691 printf("enter ? for help\n");
703 if (regs->msr & MSR_DE) {
704 bp = at_breakpoint(regs->nip);
706 regs_set_return_ip(regs, (unsigned long) &bp->instr[0]);
707 atomic_inc(&bp->ref_count);
711 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
712 bp = at_breakpoint(regs->nip);
714 int stepped = emulate_step(regs, ppc_inst_read(bp->instr));
716 regs_set_return_ip(regs, (unsigned long) &bp->instr[0]);
717 atomic_inc(&bp->ref_count);
718 } else if (stepped < 0) {
719 printf("Couldn't single-step %s instruction\n",
720 IS_RFID(ppc_inst_read(bp->instr))? "rfid": "mtmsrd");
730 xmon_touch_watchdogs();
731 local_irq_restore(flags);
733 return cmd != 'X' && cmd != EOF;
736 int xmon(struct pt_regs *excp)
741 ppc_save_regs(®s);
745 return xmon_core(excp, 0);
749 irqreturn_t xmon_irq(int irq, void *d)
752 local_irq_save(flags);
753 printf("Keyboard interrupt\n");
754 xmon(get_irq_regs());
755 local_irq_restore(flags);
759 static int xmon_bpt(struct pt_regs *regs)
762 unsigned long offset;
764 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
767 /* Are we at the trap at bp->instr[1] for some bp? */
768 bp = in_breakpoint_table(regs->nip, &offset);
769 if (bp != NULL && (offset == 4 || offset == 8)) {
770 regs_set_return_ip(regs, bp->address + offset);
771 atomic_dec(&bp->ref_count);
775 /* Are we at a breakpoint? */
776 bp = at_breakpoint(regs->nip);
785 static int xmon_sstep(struct pt_regs *regs)
793 static int xmon_break_match(struct pt_regs *regs)
797 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
799 for (i = 0; i < nr_wp_slots(); i++) {
810 static int xmon_iabr_match(struct pt_regs *regs)
812 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
820 static int xmon_ipi(struct pt_regs *regs)
823 if (in_xmon && !cpumask_test_cpu(smp_processor_id(), &cpus_in_xmon))
829 static int xmon_fault_handler(struct pt_regs *regs)
832 unsigned long offset;
834 if (in_xmon && catch_memory_errors)
835 handle_fault(regs); /* doesn't return */
837 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
838 bp = in_breakpoint_table(regs->nip, &offset);
840 regs_set_return_ip(regs, bp->address + offset);
841 atomic_dec(&bp->ref_count);
848 /* Force enable xmon if not already enabled */
849 static inline void force_enable_xmon(void)
851 /* Enable xmon hooks if needed */
853 printf("xmon: Enabling debugger hooks\n");
858 static struct bpt *at_breakpoint(unsigned long pc)
861 struct bpt *volatile bp;
864 for (i = 0; i < NBPTS; ++i, ++bp)
865 if (bp->enabled && pc == bp->address)
870 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
874 off = nip - (unsigned long)bpt_table;
875 if (off >= sizeof(bpt_table))
877 *offp = off & (BPT_SIZE - 1);
880 return bpts + (off / BPT_SIZE);
883 static struct bpt *new_breakpoint(unsigned long a)
888 bp = at_breakpoint(a);
892 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
893 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
895 bp->instr = (void *)(bpt_table + ((bp - bpts) * BPT_WORDS));
900 printf("Sorry, no free breakpoints. Please clear one first.\n");
904 static void insert_bpts(void)
907 ppc_inst_t instr, instr2;
908 struct bpt *bp, *bp2;
911 for (i = 0; i < NBPTS; ++i, ++bp) {
912 if ((bp->enabled & (BP_TRAP|BP_CIABR)) == 0)
914 if (!mread_instr(bp->address, &instr)) {
915 printf("Couldn't read instruction at %lx, "
916 "disabling breakpoint there\n", bp->address);
920 if (!can_single_step(ppc_inst_val(instr))) {
921 printf("Breakpoint at %lx is on an instruction that can't be single stepped, disabling it\n",
927 * Check the address is not a suffix by looking for a prefix in
930 if (mread_instr(bp->address - 4, &instr2) == 8) {
931 printf("Breakpoint at %lx is on the second word of a prefixed instruction, disabling it\n",
937 * We might still be a suffix - if the prefix has already been
938 * replaced by a breakpoint we won't catch it with the above
941 bp2 = at_breakpoint(bp->address - 4);
942 if (bp2 && ppc_inst_prefixed(ppc_inst_read(bp2->instr))) {
943 printf("Breakpoint at %lx is on the second word of a prefixed instruction, disabling it\n",
949 patch_instruction(bp->instr, instr);
950 patch_instruction(ppc_inst_next(bp->instr, bp->instr),
952 if (bp->enabled & BP_CIABR)
954 if (patch_instruction((u32 *)bp->address,
955 ppc_inst(bpinstr)) != 0) {
956 printf("Couldn't write instruction at %lx, "
957 "disabling breakpoint there\n", bp->address);
958 bp->enabled &= ~BP_TRAP;
964 static void insert_cpu_bpts(void)
967 struct arch_hw_breakpoint brk;
969 for (i = 0; i < nr_wp_slots(); i++) {
970 if (dabr[i].enabled) {
971 brk.address = dabr[i].address;
972 brk.type = (dabr[i].enabled & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL;
975 __set_breakpoint(i, &brk);
980 set_ciabr(iabr->address);
983 static void remove_bpts(void)
990 for (i = 0; i < NBPTS; ++i, ++bp) {
991 if ((bp->enabled & (BP_TRAP|BP_CIABR)) != BP_TRAP)
993 if (mread_instr(bp->address, &instr)
994 && ppc_inst_equal(instr, ppc_inst(bpinstr))
995 && patch_instruction(
996 (u32 *)bp->address, ppc_inst_read(bp->instr)) != 0)
997 printf("Couldn't remove breakpoint at %lx\n",
1002 static void remove_cpu_bpts(void)
1004 hw_breakpoint_disable();
1008 /* Based on uptime_proc_show(). */
1012 struct timespec64 uptime;
1014 if (setjmp(bus_error_jmp) == 0) {
1015 catch_memory_errors = 1;
1018 ktime_get_coarse_boottime_ts64(&uptime);
1019 printf("Uptime: %lu.%.2lu seconds\n", (unsigned long)uptime.tv_sec,
1020 ((unsigned long)uptime.tv_nsec / (NSEC_PER_SEC/100)));
1025 catch_memory_errors = 0;
1028 static void set_lpp_cmd(void)
1032 if (!scanhex(&lpp)) {
1033 printf("Invalid number.\n");
1036 xmon_set_pagination_lpp(lpp);
1038 /* Command interpreting routine */
1039 static char *last_cmd;
1042 cmds(struct pt_regs *excp)
1049 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1053 printf("%x:", smp_processor_id());
1054 #endif /* CONFIG_SMP */
1060 if (last_cmd == NULL)
1062 take_input(last_cmd);
1080 printf(xmon_ro_msg);
1100 prregs(excp); /* print regs */
1115 if (do_spu_cmd() == 0)
1122 if (tracing_enabled)
1126 printf(" <no input ...>\n");
1130 xmon_puts(help_string);
1150 printf(xmon_ro_msg);
1158 #if defined(CONFIG_PPC_BOOK3S_32) || defined(CONFIG_PPC_64S_HASH_MMU)
1162 #elif defined(CONFIG_44x)
1166 #elif defined(CONFIG_PPC_BOOK3E_64)
1175 printf("Unrecognized command: ");
1177 if (' ' < cmd && cmd <= '~')
1180 printf("\\x%x", cmd);
1182 } while (cmd != '\n');
1183 printf(" (type ? for help)\n");
1190 static int do_step(struct pt_regs *regs)
1192 regs_set_return_msr(regs, regs->msr | MSR_DE);
1193 mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
1198 * Step a single instruction.
1199 * Some instructions we emulate, others we execute with MSR_SE set.
1201 static int do_step(struct pt_regs *regs)
1206 force_enable_xmon();
1207 /* check we are in 64-bit kernel mode, translation enabled */
1208 if ((regs->msr & (MSR_64BIT|MSR_PR|MSR_IR)) == (MSR_64BIT|MSR_IR)) {
1209 if (mread_instr(regs->nip, &instr)) {
1210 stepped = emulate_step(regs, instr);
1212 printf("Couldn't single-step %s instruction\n",
1213 (IS_RFID(instr)? "rfid": "mtmsrd"));
1217 set_trap(regs, 0xd00);
1218 printf("stepped to ");
1219 xmon_print_symbol(regs->nip, " ", "\n");
1220 ppc_inst_dump(regs->nip, 1, 0);
1225 regs_set_return_msr(regs, regs->msr | MSR_SE);
1230 static void bootcmds(void)
1238 ppc_md.restart(tmp);
1239 } else if (cmd == 'h') {
1241 } else if (cmd == 'p') {
1242 do_kernel_power_off();
1247 static int xmon_switch_cpu(unsigned long cpu)
1255 while (!xmon_taken) {
1256 if (--timeout == 0) {
1257 if (test_and_set_bit(0, &xmon_taken))
1259 /* take control back */
1261 xmon_owner = smp_processor_id();
1262 printf("cpu 0x%lx didn't take control\n", cpu);
1270 static int xmon_batch_next_cpu(void)
1274 while (!cpumask_empty(&xmon_batch_cpus)) {
1275 cpu = cpumask_next_wrap(smp_processor_id(), &xmon_batch_cpus,
1276 xmon_batch_start_cpu, true);
1277 if (cpu >= nr_cpu_ids)
1279 if (xmon_batch_start_cpu == -1)
1280 xmon_batch_start_cpu = cpu;
1281 if (xmon_switch_cpu(cpu))
1283 cpumask_clear_cpu(cpu, &xmon_batch_cpus);
1287 printf("%x:mon> \n", smp_processor_id());
1291 static int batch_cmds(struct pt_regs *excp)
1295 /* simulate command entry */
1302 printf("%x:", smp_processor_id());
1304 printf("%c\n", (char)cmd);
1308 prregs(excp); /* print regs */
1318 cpumask_clear_cpu(smp_processor_id(), &xmon_batch_cpus);
1320 return xmon_batch_next_cpu();
1323 static int cpu_cmd(void)
1325 unsigned long cpu, first_cpu, last_cpu;
1329 xmon_batch = skipbl();
1331 switch (xmon_batch) {
1335 cpumask_copy(&xmon_batch_cpus, &cpus_in_xmon);
1336 if (cpumask_weight(&xmon_batch_cpus) <= 1) {
1337 printf("There are no other cpus in xmon\n");
1340 xmon_batch_start_cpu = -1;
1341 if (!xmon_batch_next_cpu())
1345 printf("c# only supports 'r', 'S' and 't' commands\n");
1353 if (!scanhex(&cpu)) {
1354 /* print cpus waiting or in xmon */
1355 printf("cpus stopped:");
1356 last_cpu = first_cpu = NR_CPUS;
1357 for_each_possible_cpu(cpu) {
1358 if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
1359 if (cpu == last_cpu + 1) {
1362 if (last_cpu != first_cpu)
1363 printf("-0x%lx", last_cpu);
1364 last_cpu = first_cpu = cpu;
1365 printf(" 0x%lx", cpu);
1369 if (last_cpu != first_cpu)
1370 printf("-0x%lx", last_cpu);
1374 /* try to switch to cpu specified */
1375 if (!cpumask_test_cpu(cpu, &cpus_in_xmon)) {
1376 printf("cpu 0x%lx isn't in xmon\n", cpu);
1378 printf("backtrace of paca[0x%lx].saved_r1 (possibly stale):\n", cpu);
1379 xmon_show_stack(paca_ptrs[cpu]->saved_r1, 0, 0);
1384 return xmon_switch_cpu(cpu);
1387 static int cpu_cmd(void)
1391 #endif /* CONFIG_SMP */
1393 static unsigned short fcstab[256] = {
1394 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
1395 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
1396 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
1397 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1398 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1399 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1400 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1401 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1402 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1403 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1404 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1405 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1406 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1407 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1408 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1409 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1410 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1411 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1412 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1413 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1414 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1415 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1416 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1417 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1418 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1419 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1420 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1421 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1422 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1423 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1424 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1425 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1428 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1437 if (!scanhex(&adrs))
1439 if (!scanhex(&ncsum))
1442 for (i = 0; i < ncsum; ++i) {
1443 if (mread(adrs+i, &v, 1) == 0) {
1444 printf("csum stopped at "REG"\n", adrs+i);
1449 printf("%x\n", fcs);
1453 * Check if this is a suitable place to put a breakpoint.
1455 static long check_bp_loc(unsigned long addr)
1460 if (!is_kernel_addr(addr)) {
1461 printf("Breakpoints may only be placed at kernel addresses\n");
1464 if (!mread_instr(addr, &instr)) {
1465 printf("Can't read instruction at address %lx\n", addr);
1468 if (!can_single_step(ppc_inst_val(instr))) {
1469 printf("Breakpoints may not be placed on instructions that can't be single stepped\n");
1475 static int find_free_data_bpt(void)
1479 for (i = 0; i < nr_wp_slots(); i++) {
1480 if (!dabr[i].enabled)
1483 printf("Couldn't find free breakpoint register\n");
1487 static void print_data_bpts(void)
1491 for (i = 0; i < nr_wp_slots(); i++) {
1492 if (!dabr[i].enabled)
1495 printf(" data "REG" [", dabr[i].address);
1496 if (dabr[i].enabled & 1)
1498 if (dabr[i].enabled & 2)
1504 static char *breakpoint_help_string =
1505 "Breakpoint command usage:\n"
1506 "b show breakpoints\n"
1507 "b <addr> [cnt] set breakpoint at given instr addr\n"
1508 "bc clear all breakpoints\n"
1509 "bc <n/addr> clear breakpoint number n or at addr\n"
1510 "bi <addr> [cnt] set hardware instr breakpoint (POWER8 only)\n"
1511 "bd <addr> [cnt] set hardware data breakpoint\n"
1525 case 'd': { /* bd - hardware data breakpoint */
1526 static const char badaddr[] = "Only kernel addresses are permitted for breakpoints\n";
1529 printf(xmon_ro_msg);
1532 if (!ppc_breakpoint_available()) {
1533 printf("Hardware data breakpoint not supported on this cpu\n");
1536 i = find_free_data_bpt();
1543 else if (cmd == 'w')
1547 dabr[i].address = 0;
1548 dabr[i].enabled = 0;
1549 if (scanhex(&dabr[i].address)) {
1550 if (!is_kernel_addr(dabr[i].address)) {
1554 dabr[i].address &= ~HW_BRK_TYPE_DABR;
1555 dabr[i].enabled = mode | BP_DABR;
1558 force_enable_xmon();
1562 case 'i': /* bi - hardware instr breakpoint */
1564 printf(xmon_ro_msg);
1567 if (!cpu_has_feature(CPU_FTR_ARCH_207S)) {
1568 printf("Hardware instruction breakpoint "
1569 "not supported on this cpu\n");
1573 iabr->enabled &= ~BP_CIABR;
1578 if (!check_bp_loc(a))
1580 bp = new_breakpoint(a);
1582 bp->enabled |= BP_CIABR;
1584 force_enable_xmon();
1590 /* clear all breakpoints */
1591 for (i = 0; i < NBPTS; ++i)
1592 bpts[i].enabled = 0;
1594 for (i = 0; i < nr_wp_slots(); i++)
1595 dabr[i].enabled = 0;
1597 printf("All breakpoints cleared\n");
1601 if (a <= NBPTS && a >= 1) {
1602 /* assume a breakpoint number */
1603 bp = &bpts[a-1]; /* bp nums are 1 based */
1605 /* assume a breakpoint address */
1606 bp = at_breakpoint(a);
1608 printf("No breakpoint at %lx\n", a);
1613 printf("Cleared breakpoint %tx (", BP_NUM(bp));
1614 xmon_print_symbol(bp->address, " ", ")\n");
1622 printf(breakpoint_help_string);
1627 if (xmon_is_ro || !scanhex(&a)) {
1628 /* print all breakpoints */
1629 printf(" type address\n");
1631 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1634 printf("%tx %s ", BP_NUM(bp),
1635 (bp->enabled & BP_CIABR) ? "inst": "trap");
1636 xmon_print_symbol(bp->address, " ", "\n");
1641 if (!check_bp_loc(a))
1643 bp = new_breakpoint(a);
1645 bp->enabled |= BP_TRAP;
1646 force_enable_xmon();
1652 /* Very cheap human name for vector lookup. */
1654 const char *getvecname(unsigned long vec)
1659 case 0x100: ret = "(System Reset)"; break;
1660 case 0x200: ret = "(Machine Check)"; break;
1661 case 0x300: ret = "(Data Access)"; break;
1663 if (radix_enabled())
1664 ret = "(Data Access Out of Range)";
1666 ret = "(Data SLB Access)";
1668 case 0x400: ret = "(Instruction Access)"; break;
1670 if (radix_enabled())
1671 ret = "(Instruction Access Out of Range)";
1673 ret = "(Instruction SLB Access)";
1675 case 0x500: ret = "(Hardware Interrupt)"; break;
1676 case 0x600: ret = "(Alignment)"; break;
1677 case 0x700: ret = "(Program Check)"; break;
1678 case 0x800: ret = "(FPU Unavailable)"; break;
1679 case 0x900: ret = "(Decrementer)"; break;
1680 case 0x980: ret = "(Hypervisor Decrementer)"; break;
1681 case 0xa00: ret = "(Doorbell)"; break;
1682 case 0xc00: ret = "(System Call)"; break;
1683 case 0xd00: ret = "(Single Step)"; break;
1684 case 0xe40: ret = "(Emulation Assist)"; break;
1685 case 0xe60: ret = "(HMI)"; break;
1686 case 0xe80: ret = "(Hypervisor Doorbell)"; break;
1687 case 0xf00: ret = "(Performance Monitor)"; break;
1688 case 0xf20: ret = "(Altivec Unavailable)"; break;
1689 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1690 case 0x1500: ret = "(Denormalisation)"; break;
1691 case 0x1700: ret = "(Altivec Assist)"; break;
1692 case 0x3000: ret = "(System Call Vectored)"; break;
1698 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1699 unsigned long *endp)
1701 unsigned long size, offset;
1704 *startp = *endp = 0;
1707 if (setjmp(bus_error_jmp) == 0) {
1708 catch_memory_errors = 1;
1710 name = kallsyms_lookup(pc, &size, &offset, NULL, tmpstr);
1712 *startp = pc - offset;
1713 *endp = pc - offset + size;
1717 catch_memory_errors = 0;
1720 #define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1722 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1725 int max_to_print = 64;
1727 unsigned long newsp;
1728 unsigned long marker;
1729 struct pt_regs regs;
1731 while (max_to_print--) {
1732 if (!is_kernel_addr(sp)) {
1734 printf("SP (%lx) is in userspace\n", sp);
1738 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1739 || !mread(sp, &newsp, sizeof(unsigned long))) {
1740 printf("Couldn't read stack frame at %lx\n", sp);
1745 * For the first stack frame, try to work out if
1746 * LR and/or the saved LR value in the bottommost
1747 * stack frame are valid.
1749 if ((pc | lr) != 0) {
1750 unsigned long fnstart, fnend;
1751 unsigned long nextip;
1754 get_function_bounds(pc, &fnstart, &fnend);
1757 mread(newsp + LRSAVE_OFFSET, &nextip,
1758 sizeof(unsigned long));
1760 if (!is_kernel_addr(lr)
1761 || (fnstart <= lr && lr < fnend))
1763 } else if (lr == nextip) {
1765 } else if (is_kernel_addr(lr)
1766 && !(fnstart <= lr && lr < fnend)) {
1767 printf("[link register ] ");
1768 xmon_print_symbol(lr, " ", "\n");
1771 printf("["REG"] ", sp);
1772 xmon_print_symbol(ip, " ", " (unreliable)\n");
1777 printf("["REG"] ", sp);
1778 xmon_print_symbol(ip, " ", "\n");
1781 /* Look for "regs" marker to see if this is
1782 an exception frame. */
1783 if (mread(sp + STACK_INT_FRAME_MARKER, &marker, sizeof(unsigned long))
1784 && marker == STACK_FRAME_REGS_MARKER) {
1785 if (mread(sp + STACK_INT_FRAME_REGS, ®s, sizeof(regs)) != sizeof(regs)) {
1786 printf("Couldn't read registers at %lx\n",
1787 sp + STACK_INT_FRAME_REGS);
1790 printf("--- Exception: %lx %s at ", regs.trap,
1791 getvecname(TRAP(®s)));
1794 xmon_print_symbol(pc, " ", "\n");
1804 static void backtrace(struct pt_regs *excp)
1809 xmon_show_stack(sp, 0, 0);
1811 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1815 static void print_bug_trap(struct pt_regs *regs)
1818 const struct bug_entry *bug;
1821 if (user_mode(regs))
1823 addr = regs->nip; /* address of trap instruction */
1824 if (!is_kernel_addr(addr))
1826 bug = find_bug(regs->nip);
1829 if (is_warning_bug(bug))
1832 #ifdef CONFIG_DEBUG_BUGVERBOSE
1833 printf("kernel BUG at %s:%u!\n",
1834 (char *)bug + bug->file_disp, bug->line);
1836 printf("kernel BUG at %px!\n", (void *)bug + bug->bug_addr_disp);
1838 #endif /* CONFIG_BUG */
1841 static void excprint(struct pt_regs *fp)
1846 printf("cpu 0x%x: ", smp_processor_id());
1847 #endif /* CONFIG_SMP */
1850 printf("Vector: %lx %s at [%px]\n", fp->trap, getvecname(trap), fp);
1852 xmon_print_symbol(fp->nip, ": ", "\n");
1855 xmon_print_symbol(fp->link, ": ", "\n");
1857 printf(" sp: %lx\n", fp->gpr[1]);
1858 printf(" msr: %lx\n", fp->msr);
1860 if (trap == INTERRUPT_DATA_STORAGE ||
1861 trap == INTERRUPT_DATA_SEGMENT ||
1862 trap == INTERRUPT_ALIGNMENT ||
1863 trap == INTERRUPT_MACHINE_CHECK) {
1864 printf(" dar: %lx\n", fp->dar);
1865 if (trap != INTERRUPT_DATA_SEGMENT)
1866 printf(" dsisr: %lx\n", fp->dsisr);
1869 printf(" current = 0x%px\n", current);
1871 printf(" paca = 0x%px\t irqmask: 0x%02x\t irq_happened: 0x%02x\n",
1872 local_paca, local_paca->irq_soft_mask, local_paca->irq_happened);
1875 printf(" pid = %d, comm = %s\n",
1876 current->pid, current->comm);
1879 if (trap == INTERRUPT_PROGRAM)
1882 printf(linux_banner);
1885 static void prregs(struct pt_regs *fp)
1889 struct pt_regs regs;
1891 if (scanhex(&base)) {
1892 if (setjmp(bus_error_jmp) == 0) {
1893 catch_memory_errors = 1;
1895 regs = *(struct pt_regs *)base;
1899 catch_memory_errors = 0;
1900 printf("*** Error reading registers from "REG"\n",
1904 catch_memory_errors = 0;
1909 #define R_PER_LINE 2
1911 #define R_PER_LINE 4
1914 for (n = 0; n < 32; ++n) {
1915 printf("R%.2d = "REG"%s", n, fp->gpr[n],
1916 (n % R_PER_LINE) == R_PER_LINE - 1 ? "\n" : " ");
1920 xmon_print_symbol(fp->nip, " ", "\n");
1921 if (!trap_is_syscall(fp) && cpu_has_feature(CPU_FTR_CFAR)) {
1923 xmon_print_symbol(fp->orig_gpr3, " ", "\n");
1926 xmon_print_symbol(fp->link, " ", "\n");
1927 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
1928 printf("ctr = "REG" xer = "REG" trap = %4lx\n",
1929 fp->ctr, fp->xer, fp->trap);
1931 if (trap == INTERRUPT_DATA_STORAGE ||
1932 trap == INTERRUPT_DATA_SEGMENT ||
1933 trap == INTERRUPT_ALIGNMENT)
1934 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1937 static void cacheflush(void)
1940 unsigned long nflush;
1945 scanhex((void *)&adrs);
1950 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1951 if (setjmp(bus_error_jmp) == 0) {
1952 catch_memory_errors = 1;
1955 if (cmd != 'i' || IS_ENABLED(CONFIG_PPC_BOOK3S_64)) {
1956 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1957 cflush((void *) adrs);
1959 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1960 cinval((void *) adrs);
1963 /* wait a little while to see if we get a machine check */
1966 catch_memory_errors = 0;
1969 extern unsigned long xmon_mfspr(int spr, unsigned long default_value);
1970 extern void xmon_mtspr(int spr, unsigned long value);
1973 read_spr(int n, unsigned long *vp)
1975 unsigned long ret = -1UL;
1978 if (setjmp(bus_error_jmp) == 0) {
1979 catch_spr_faults = 1;
1982 ret = xmon_mfspr(n, *vp);
1988 catch_spr_faults = 0;
1994 write_spr(int n, unsigned long val)
1997 printf(xmon_ro_msg);
2001 if (setjmp(bus_error_jmp) == 0) {
2002 catch_spr_faults = 1;
2009 printf("SPR 0x%03x (%4d) Faulted during write\n", n, n);
2011 catch_spr_faults = 0;
2014 static void dump_206_sprs(void)
2017 if (!cpu_has_feature(CPU_FTR_ARCH_206))
2020 /* Actually some of these pre-date 2.06, but whatever */
2022 printf("srr0 = %.16lx srr1 = %.16lx dsisr = %.8lx\n",
2023 mfspr(SPRN_SRR0), mfspr(SPRN_SRR1), mfspr(SPRN_DSISR));
2024 printf("dscr = %.16lx ppr = %.16lx pir = %.8lx\n",
2025 mfspr(SPRN_DSCR), mfspr(SPRN_PPR), mfspr(SPRN_PIR));
2026 printf("amr = %.16lx uamor = %.16lx\n",
2027 mfspr(SPRN_AMR), mfspr(SPRN_UAMOR));
2029 if (!(mfmsr() & MSR_HV))
2032 printf("sdr1 = %.16lx hdar = %.16lx hdsisr = %.8lx\n",
2033 mfspr(SPRN_SDR1), mfspr(SPRN_HDAR), mfspr(SPRN_HDSISR));
2034 printf("hsrr0 = %.16lx hsrr1 = %.16lx hdec = %.16lx\n",
2035 mfspr(SPRN_HSRR0), mfspr(SPRN_HSRR1), mfspr(SPRN_HDEC));
2036 printf("lpcr = %.16lx pcr = %.16lx lpidr = %.8lx\n",
2037 mfspr(SPRN_LPCR), mfspr(SPRN_PCR), mfspr(SPRN_LPID));
2038 printf("hsprg0 = %.16lx hsprg1 = %.16lx amor = %.16lx\n",
2039 mfspr(SPRN_HSPRG0), mfspr(SPRN_HSPRG1), mfspr(SPRN_AMOR));
2040 printf("dabr = %.16lx dabrx = %.16lx\n",
2041 mfspr(SPRN_DABR), mfspr(SPRN_DABRX));
2045 static void dump_207_sprs(void)
2050 if (!cpu_has_feature(CPU_FTR_ARCH_207S))
2053 printf("dpdes = %.16lx tir = %.16lx cir = %.8lx\n",
2054 mfspr(SPRN_DPDES), mfspr(SPRN_TIR), mfspr(SPRN_CIR));
2056 printf("fscr = %.16lx tar = %.16lx pspb = %.8lx\n",
2057 mfspr(SPRN_FSCR), mfspr(SPRN_TAR), mfspr(SPRN_PSPB));
2061 /* Only if TM has been enabled in the kernel */
2062 printf("tfhar = %.16lx tfiar = %.16lx texasr = %.16lx\n",
2063 mfspr(SPRN_TFHAR), mfspr(SPRN_TFIAR),
2064 mfspr(SPRN_TEXASR));
2067 printf("mmcr0 = %.16lx mmcr1 = %.16lx mmcr2 = %.16lx\n",
2068 mfspr(SPRN_MMCR0), mfspr(SPRN_MMCR1), mfspr(SPRN_MMCR2));
2069 printf("pmc1 = %.8lx pmc2 = %.8lx pmc3 = %.8lx pmc4 = %.8lx\n",
2070 mfspr(SPRN_PMC1), mfspr(SPRN_PMC2),
2071 mfspr(SPRN_PMC3), mfspr(SPRN_PMC4));
2072 printf("mmcra = %.16lx siar = %.16lx pmc5 = %.8lx\n",
2073 mfspr(SPRN_MMCRA), mfspr(SPRN_SIAR), mfspr(SPRN_PMC5));
2074 printf("sdar = %.16lx sier = %.16lx pmc6 = %.8lx\n",
2075 mfspr(SPRN_SDAR), mfspr(SPRN_SIER), mfspr(SPRN_PMC6));
2076 printf("ebbhr = %.16lx ebbrr = %.16lx bescr = %.16lx\n",
2077 mfspr(SPRN_EBBHR), mfspr(SPRN_EBBRR), mfspr(SPRN_BESCR));
2078 printf("iamr = %.16lx\n", mfspr(SPRN_IAMR));
2080 if (!(msr & MSR_HV))
2083 printf("hfscr = %.16lx dhdes = %.16lx rpr = %.16lx\n",
2084 mfspr(SPRN_HFSCR), mfspr(SPRN_DHDES), mfspr(SPRN_RPR));
2085 printf("dawr0 = %.16lx dawrx0 = %.16lx\n",
2086 mfspr(SPRN_DAWR0), mfspr(SPRN_DAWRX0));
2087 if (nr_wp_slots() > 1) {
2088 printf("dawr1 = %.16lx dawrx1 = %.16lx\n",
2089 mfspr(SPRN_DAWR1), mfspr(SPRN_DAWRX1));
2091 printf("ciabr = %.16lx\n", mfspr(SPRN_CIABR));
2095 static void dump_300_sprs(void)
2098 bool hv = mfmsr() & MSR_HV;
2100 if (!cpu_has_feature(CPU_FTR_ARCH_300))
2103 if (cpu_has_feature(CPU_FTR_P9_TIDR)) {
2104 printf("pidr = %.16lx tidr = %.16lx\n",
2105 mfspr(SPRN_PID), mfspr(SPRN_TIDR));
2107 printf("pidr = %.16lx\n",
2111 printf("psscr = %.16lx\n",
2112 hv ? mfspr(SPRN_PSSCR) : mfspr(SPRN_PSSCR_PR));
2117 printf("ptcr = %.16lx asdr = %.16lx\n",
2118 mfspr(SPRN_PTCR), mfspr(SPRN_ASDR));
2122 static void dump_310_sprs(void)
2125 if (!cpu_has_feature(CPU_FTR_ARCH_31))
2128 printf("mmcr3 = %.16lx, sier2 = %.16lx, sier3 = %.16lx\n",
2129 mfspr(SPRN_MMCR3), mfspr(SPRN_SIER2), mfspr(SPRN_SIER3));
2134 static void dump_one_spr(int spr, bool show_unimplemented)
2139 if (!read_spr(spr, &val)) {
2140 printf("SPR 0x%03x (%4d) Faulted during read\n", spr, spr);
2144 if (val == 0xdeadbeef) {
2145 /* Looks like read was a nop, confirm */
2147 if (!read_spr(spr, &val)) {
2148 printf("SPR 0x%03x (%4d) Faulted during read\n", spr, spr);
2152 if (val == 0x0badcafe) {
2153 if (show_unimplemented)
2154 printf("SPR 0x%03x (%4d) Unimplemented\n", spr, spr);
2159 printf("SPR 0x%03x (%4d) = 0x%lx\n", spr, spr, val);
2162 static void super_regs(void)
2164 static unsigned long regno;
2172 unsigned long sp, toc;
2173 asm("mr %0,1" : "=r" (sp) :);
2174 asm("mr %0,2" : "=r" (toc) :);
2176 printf("msr = "REG" sprg0 = "REG"\n",
2177 mfmsr(), mfspr(SPRN_SPRG0));
2178 printf("pvr = "REG" sprg1 = "REG"\n",
2179 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
2180 printf("dec = "REG" sprg2 = "REG"\n",
2181 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
2182 printf("sp = "REG" sprg3 = "REG"\n", sp, mfspr(SPRN_SPRG3));
2183 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
2196 read_spr(regno, &val);
2198 write_spr(regno, val);
2199 dump_one_spr(regno, true);
2204 dump_one_spr(regno, true);
2208 for (spr = 1; spr < 1024; ++spr)
2209 dump_one_spr(spr, false);
2217 * Stuff for reading and writing memory safely
2220 mread(unsigned long adrs, void *buf, int size)
2226 if (setjmp(bus_error_jmp) == 0) {
2227 catch_memory_errors = 1;
2233 *(u16 *)q = *(u16 *)p;
2236 *(u32 *)q = *(u32 *)p;
2239 *(u64 *)q = *(u64 *)p;
2242 for( ; n < size; ++n) {
2248 /* wait a little while to see if we get a machine check */
2252 catch_memory_errors = 0;
2257 mwrite(unsigned long adrs, void *buf, int size)
2265 printf(xmon_ro_msg);
2269 if (setjmp(bus_error_jmp) == 0) {
2270 catch_memory_errors = 1;
2276 *(u16 *)p = *(u16 *)q;
2279 *(u32 *)p = *(u32 *)q;
2282 *(u64 *)p = *(u64 *)q;
2285 for ( ; n < size; ++n) {
2291 /* wait a little while to see if we get a machine check */
2295 printf("*** Error writing address "REG"\n", adrs + n);
2297 catch_memory_errors = 0;
2302 mread_instr(unsigned long adrs, ppc_inst_t *instr)
2307 if (setjmp(bus_error_jmp) == 0) {
2308 catch_memory_errors = 1;
2310 *instr = ppc_inst_read((u32 *)adrs);
2312 /* wait a little while to see if we get a machine check */
2314 n = ppc_inst_len(*instr);
2316 catch_memory_errors = 0;
2320 static int fault_type;
2321 static int fault_except;
2322 static char *fault_chars[] = { "--", "**", "##" };
2324 static int handle_fault(struct pt_regs *regs)
2326 fault_except = TRAP(regs);
2327 switch (TRAP(regs)) {
2339 longjmp(bus_error_jmp, 1);
2344 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
2347 byterev(unsigned char *val, int size)
2353 SWAP(val[0], val[1], t);
2356 SWAP(val[0], val[3], t);
2357 SWAP(val[1], val[2], t);
2359 case 8: /* is there really any use for this? */
2360 SWAP(val[0], val[7], t);
2361 SWAP(val[1], val[6], t);
2362 SWAP(val[2], val[5], t);
2363 SWAP(val[3], val[4], t);
2371 static char *memex_help_string =
2372 "Memory examine command usage:\n"
2373 "m [addr] [flags] examine/change memory\n"
2374 " addr is optional. will start where left off.\n"
2375 " flags may include chars from this set:\n"
2376 " b modify by bytes (default)\n"
2377 " w modify by words (2 byte)\n"
2378 " l modify by longs (4 byte)\n"
2379 " d modify by doubleword (8 byte)\n"
2380 " r toggle reverse byte order mode\n"
2381 " n do not read memory (for i/o spaces)\n"
2382 " . ok to read (default)\n"
2383 "NOTE: flags are saved as defaults\n"
2386 static char *memex_subcmd_help_string =
2387 "Memory examine subcommands:\n"
2388 " hexval write this val to current location\n"
2389 " 'string' write chars from string to this location\n"
2390 " ' increment address\n"
2391 " ^ decrement address\n"
2392 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
2393 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
2394 " ` clear no-read flag\n"
2395 " ; stay at this addr\n"
2396 " v change to byte mode\n"
2397 " w change to word (2 byte) mode\n"
2398 " l change to long (4 byte) mode\n"
2399 " u change to doubleword (8 byte) mode\n"
2400 " m addr change current addr\n"
2401 " n toggle no-read flag\n"
2402 " r toggle byte reverse flag\n"
2403 " < count back up count bytes\n"
2404 " > count skip forward count bytes\n"
2405 " x exit this mode\n"
2411 int cmd, inc, i, nslash;
2413 unsigned char val[16];
2415 scanhex((void *)&adrs);
2418 printf(memex_help_string);
2424 while ((cmd = skipbl()) != '\n') {
2426 case 'b': size = 1; break;
2427 case 'w': size = 2; break;
2428 case 'l': size = 4; break;
2429 case 'd': size = 8; break;
2430 case 'r': brev = !brev; break;
2431 case 'n': mnoread = 1; break;
2432 case '.': mnoread = 0; break;
2441 n = mread(adrs, val, size);
2442 printf(REG"%c", adrs, brev? 'r': ' ');
2447 for (i = 0; i < n; ++i)
2448 printf("%.2x", val[i]);
2449 for (; i < size; ++i)
2450 printf("%s", fault_chars[fault_type]);
2457 for (i = 0; i < size; ++i)
2458 val[i] = n >> (i * 8);
2461 mwrite(adrs, val, size);
2474 else if( n == '\'' )
2476 for (i = 0; i < size; ++i)
2477 val[i] = n >> (i * 8);
2480 mwrite(adrs, val, size);
2516 adrs -= 1 << nslash;
2520 adrs += 1 << nslash;
2524 adrs += 1 << -nslash;
2528 adrs -= 1 << -nslash;
2531 scanhex((void *)&adrs);
2550 printf(memex_subcmd_help_string);
2565 case 'n': c = '\n'; break;
2566 case 'r': c = '\r'; break;
2567 case 'b': c = '\b'; break;
2568 case 't': c = '\t'; break;
2573 static void xmon_rawdump (unsigned long adrs, long ndump)
2576 unsigned char temp[16];
2578 for (n = ndump; n > 0;) {
2580 nr = mread(adrs, temp, r);
2582 for (m = 0; m < r; ++m) {
2584 printf("%.2x", temp[m]);
2586 printf("%s", fault_chars[fault_type]);
2595 static void dump_tracing(void)
2601 ftrace_dump(DUMP_ORIG);
2603 ftrace_dump(DUMP_ALL);
2607 static void dump_one_paca(int cpu)
2609 struct paca_struct *p;
2610 #ifdef CONFIG_PPC_64S_HASH_MMU
2614 if (setjmp(bus_error_jmp) != 0) {
2615 printf("*** Error dumping paca for cpu 0x%x!\n", cpu);
2619 catch_memory_errors = 1;
2624 printf("paca for cpu 0x%x @ %px:\n", cpu, p);
2626 printf(" %-*s = %s\n", 25, "possible", cpu_possible(cpu) ? "yes" : "no");
2627 printf(" %-*s = %s\n", 25, "present", cpu_present(cpu) ? "yes" : "no");
2628 printf(" %-*s = %s\n", 25, "online", cpu_online(cpu) ? "yes" : "no");
2630 #define DUMP(paca, name, format) \
2631 printf(" %-*s = "format"\t(0x%lx)\n", 25, #name, 18, paca->name, \
2632 offsetof(struct paca_struct, name));
2634 DUMP(p, lock_token, "%#-*x");
2635 DUMP(p, paca_index, "%#-*x");
2636 #ifndef CONFIG_PPC_KERNEL_PCREL
2637 DUMP(p, kernel_toc, "%#-*llx");
2639 DUMP(p, kernelbase, "%#-*llx");
2640 DUMP(p, kernel_msr, "%#-*llx");
2641 DUMP(p, emergency_sp, "%-*px");
2642 #ifdef CONFIG_PPC_BOOK3S_64
2643 DUMP(p, nmi_emergency_sp, "%-*px");
2644 DUMP(p, mc_emergency_sp, "%-*px");
2645 DUMP(p, in_nmi, "%#-*x");
2646 DUMP(p, in_mce, "%#-*x");
2647 DUMP(p, hmi_event_available, "%#-*x");
2649 DUMP(p, data_offset, "%#-*llx");
2650 DUMP(p, hw_cpu_id, "%#-*x");
2651 DUMP(p, cpu_start, "%#-*x");
2652 DUMP(p, kexec_state, "%#-*x");
2653 #ifdef CONFIG_PPC_BOOK3S_64
2654 #ifdef CONFIG_PPC_64S_HASH_MMU
2655 if (!early_radix_enabled()) {
2656 for (i = 0; i < SLB_NUM_BOLTED; i++) {
2659 if (!p->slb_shadow_ptr)
2662 esid = be64_to_cpu(p->slb_shadow_ptr->save_area[i].esid);
2663 vsid = be64_to_cpu(p->slb_shadow_ptr->save_area[i].vsid);
2666 printf(" %-*s[%d] = 0x%016llx 0x%016llx\n",
2667 22, "slb_shadow", i, esid, vsid);
2670 DUMP(p, vmalloc_sllp, "%#-*x");
2671 DUMP(p, stab_rr, "%#-*x");
2672 DUMP(p, slb_used_bitmap, "%#-*x");
2673 DUMP(p, slb_kern_bitmap, "%#-*x");
2675 if (!early_cpu_has_feature(CPU_FTR_ARCH_300)) {
2676 DUMP(p, slb_cache_ptr, "%#-*x");
2677 for (i = 0; i < SLB_CACHE_ENTRIES; i++)
2678 printf(" %-*s[%d] = 0x%016x\n",
2679 22, "slb_cache", i, p->slb_cache[i]);
2684 DUMP(p, rfi_flush_fallback_area, "%-*px");
2686 DUMP(p, dscr_default, "%#-*llx");
2687 #ifdef CONFIG_PPC_BOOK3E_64
2688 DUMP(p, pgd, "%-*px");
2689 DUMP(p, kernel_pgd, "%-*px");
2690 DUMP(p, tcd_ptr, "%-*px");
2691 DUMP(p, mc_kstack, "%-*px");
2692 DUMP(p, crit_kstack, "%-*px");
2693 DUMP(p, dbg_kstack, "%-*px");
2695 DUMP(p, __current, "%-*px");
2696 DUMP(p, kstack, "%#-*llx");
2697 printf(" %-*s = 0x%016llx\n", 25, "kstack_base", p->kstack & ~(THREAD_SIZE - 1));
2698 #ifdef CONFIG_STACKPROTECTOR
2699 DUMP(p, canary, "%#-*lx");
2701 DUMP(p, saved_r1, "%#-*llx");
2702 #ifdef CONFIG_PPC_BOOK3E_64
2703 DUMP(p, trap_save, "%#-*x");
2705 DUMP(p, irq_soft_mask, "%#-*x");
2706 DUMP(p, irq_happened, "%#-*x");
2707 #ifdef CONFIG_MMIOWB
2708 DUMP(p, mmiowb_state.nesting_count, "%#-*x");
2709 DUMP(p, mmiowb_state.mmiowb_pending, "%#-*x");
2711 DUMP(p, irq_work_pending, "%#-*x");
2712 DUMP(p, sprg_vdso, "%#-*llx");
2714 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
2715 DUMP(p, tm_scratch, "%#-*llx");
2718 #ifdef CONFIG_PPC_POWERNV
2719 DUMP(p, idle_state, "%#-*lx");
2720 if (!early_cpu_has_feature(CPU_FTR_ARCH_300)) {
2721 DUMP(p, thread_idle_state, "%#-*x");
2722 DUMP(p, subcore_sibling_mask, "%#-*x");
2724 #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
2725 DUMP(p, requested_psscr, "%#-*llx");
2726 DUMP(p, dont_stop.counter, "%#-*x");
2731 DUMP(p, accounting.utime, "%#-*lx");
2732 DUMP(p, accounting.stime, "%#-*lx");
2733 #ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
2734 DUMP(p, accounting.utime_scaled, "%#-*lx");
2736 DUMP(p, accounting.starttime, "%#-*lx");
2737 DUMP(p, accounting.starttime_user, "%#-*lx");
2738 #ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
2739 DUMP(p, accounting.startspurr, "%#-*lx");
2740 DUMP(p, accounting.utime_sspurr, "%#-*lx");
2742 DUMP(p, accounting.steal_time, "%#-*lx");
2745 catch_memory_errors = 0;
2749 static void dump_all_pacas(void)
2753 if (num_possible_cpus() == 0) {
2754 printf("No possible cpus, use 'dp #' to dump individual cpus\n");
2758 for_each_possible_cpu(cpu)
2762 static void dump_pacas(void)
2773 termch = c; /* Put c back, it wasn't 'a' */
2778 dump_one_paca(xmon_owner);
2782 #ifdef CONFIG_PPC_POWERNV
2783 static void dump_one_xive(int cpu)
2785 unsigned int hwid = get_hard_smp_processor_id(cpu);
2786 bool hv = cpu_has_feature(CPU_FTR_HVMODE);
2789 opal_xive_dump(XIVE_DUMP_TM_HYP, hwid);
2790 opal_xive_dump(XIVE_DUMP_TM_POOL, hwid);
2791 opal_xive_dump(XIVE_DUMP_TM_OS, hwid);
2792 opal_xive_dump(XIVE_DUMP_TM_USER, hwid);
2793 opal_xive_dump(XIVE_DUMP_VP, hwid);
2794 opal_xive_dump(XIVE_DUMP_EMU_STATE, hwid);
2797 if (setjmp(bus_error_jmp) != 0) {
2798 catch_memory_errors = 0;
2799 printf("*** Error dumping xive on cpu %d\n", cpu);
2803 catch_memory_errors = 1;
2805 xmon_xive_do_dump(cpu);
2808 catch_memory_errors = 0;
2811 static void dump_all_xives(void)
2815 if (num_online_cpus() == 0) {
2816 printf("No possible cpus, use 'dx #' to dump individual cpus\n");
2820 for_each_online_cpu(cpu)
2824 static void dump_xives(void)
2829 if (!xive_enabled()) {
2830 printf("Xive disabled on this system\n");
2838 } else if (c == 'i') {
2840 xmon_xive_get_irq_config(num, NULL);
2842 xmon_xive_get_irq_all();
2846 termch = c; /* Put c back, it wasn't 'a' */
2851 dump_one_xive(xmon_owner);
2853 #endif /* CONFIG_PPC_POWERNV */
2855 static void dump_by_size(unsigned long addr, long count, int size)
2857 unsigned char temp[16];
2861 count = ALIGN(count, 16);
2863 for (i = 0; i < count; i += 16, addr += 16) {
2866 if (mread(addr, temp, 16) != 16) {
2867 printf("\nFaulted reading %d bytes from 0x"REG"\n", 16, addr);
2871 for (j = 0; j < 16; j += size) {
2874 case 1: val = temp[j]; break;
2875 case 2: val = *(u16 *)&temp[j]; break;
2876 case 4: val = *(u32 *)&temp[j]; break;
2877 case 8: val = *(u64 *)&temp[j]; break;
2881 printf("%0*llx", size * 2, val);
2884 for (j = 0; j < 16; ++j) {
2886 putchar(' ' <= val && val <= '~' ? val : '.');
2895 static char last[] = { "d?\n" };
2902 xmon_start_pagination();
2904 xmon_end_pagination();
2908 #ifdef CONFIG_PPC_POWERNV
2910 xmon_start_pagination();
2912 xmon_end_pagination();
2925 scanhex((void *)&adrs);
2932 else if (nidump > MAX_IDUMP)
2934 adrs += ppc_inst_dump(adrs, nidump, 1);
2936 } else if (c == 'l') {
2938 } else if (c == 'o') {
2940 } else if (c == 'v') {
2941 /* dump virtual to physical translation */
2943 } else if (c == 'r') {
2947 xmon_rawdump(adrs, ndump);
2954 else if (ndump > MAX_DUMP)
2962 ndump = ALIGN(ndump, 16);
2963 dump_by_size(adrs, ndump, c - '0');
2968 prdump(adrs, ndump);
2977 prdump(unsigned long adrs, long ndump)
2979 long n, m, c, r, nr;
2980 unsigned char temp[16];
2982 for (n = ndump; n > 0;) {
2986 nr = mread(adrs, temp, r);
2988 for (m = 0; m < r; ++m) {
2989 if ((m & (sizeof(long) - 1)) == 0 && m > 0)
2992 printf("%.2x", temp[m]);
2994 printf("%s", fault_chars[fault_type]);
2996 for (; m < 16; ++m) {
2997 if ((m & (sizeof(long) - 1)) == 0)
3002 for (m = 0; m < r; ++m) {
3005 putchar(' ' <= c && c <= '~'? c: '.');
3018 typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr);
3021 generic_inst_dump(unsigned long adr, long count, int praddr,
3022 instruction_dump_func dump_func)
3025 unsigned long first_adr;
3026 ppc_inst_t inst, last_inst = ppc_inst(0);
3029 for (first_adr = adr; count > 0; --count, adr += ppc_inst_len(inst)) {
3030 nr = mread_instr(adr, &inst);
3033 const char *x = fault_chars[fault_type];
3034 printf(REG" %s%s%s%s\n", adr, x, x, x, x);
3038 if (adr > first_adr && ppc_inst_equal(inst, last_inst)) {
3048 printf(REG" %08lx", adr, ppc_inst_as_ulong(inst));
3050 if (!ppc_inst_prefixed(inst))
3051 dump_func(ppc_inst_val(inst), adr);
3053 dump_func(ppc_inst_as_ulong(inst), adr);
3056 return adr - first_adr;
3060 ppc_inst_dump(unsigned long adr, long count, int praddr)
3062 return generic_inst_dump(adr, count, praddr, print_insn_powerpc);
3066 print_address(unsigned long addr)
3068 xmon_print_symbol(addr, "\t# ", "");
3074 struct kmsg_dump_iter iter;
3075 static unsigned char buf[1024];
3078 if (setjmp(bus_error_jmp) != 0) {
3079 printf("Error dumping printk buffer!\n");
3083 catch_memory_errors = 1;
3086 kmsg_dump_rewind(&iter);
3087 xmon_start_pagination();
3088 while (kmsg_dump_get_line(&iter, false, buf, sizeof(buf), &len)) {
3092 xmon_end_pagination();
3095 /* wait a little while to see if we get a machine check */
3097 catch_memory_errors = 0;
3100 #ifdef CONFIG_PPC_POWERNV
3101 static void dump_opal_msglog(void)
3103 unsigned char buf[128];
3105 volatile loff_t pos = 0;
3107 if (!firmware_has_feature(FW_FEATURE_OPAL)) {
3108 printf("Machine is not running OPAL firmware.\n");
3112 if (setjmp(bus_error_jmp) != 0) {
3113 printf("Error dumping OPAL msglog!\n");
3117 catch_memory_errors = 1;
3120 xmon_start_pagination();
3121 while ((res = opal_msglog_copy(buf, pos, sizeof(buf) - 1))) {
3123 printf("Error dumping OPAL msglog! Error: %zd\n", res);
3130 xmon_end_pagination();
3133 /* wait a little while to see if we get a machine check */
3135 catch_memory_errors = 0;
3140 * Memory operations - move, set, print differences
3142 static unsigned long mdest; /* destination address */
3143 static unsigned long msrc; /* source address */
3144 static unsigned long mval; /* byte value to set memory to */
3145 static unsigned long mcount; /* # bytes to affect */
3146 static unsigned long mdiffs; /* max # differences to print */
3151 scanhex((void *)&mdest);
3152 if( termch != '\n' )
3154 scanhex((void *)(cmd == 's'? &mval: &msrc));
3155 if( termch != '\n' )
3157 scanhex((void *)&mcount);
3161 printf(xmon_ro_msg);
3164 memmove((void *)mdest, (void *)msrc, mcount);
3168 printf(xmon_ro_msg);
3171 memset((void *)mdest, mval, mcount);
3174 if( termch != '\n' )
3176 scanhex((void *)&mdiffs);
3177 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
3183 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
3188 for( n = nb; n > 0; --n )
3189 if( *p1++ != *p2++ )
3190 if( ++prt <= maxpr )
3191 printf("%px %.2x # %px %.2x\n", p1 - 1,
3192 p1[-1], p2 - 1, p2[-1]);
3194 printf("Total of %d differences\n", prt);
3197 static unsigned mend;
3198 static unsigned mask;
3204 unsigned char val[4];
3207 scanhex((void *)&mdest);
3208 if (termch != '\n') {
3210 scanhex((void *)&mend);
3211 if (termch != '\n') {
3213 scanhex((void *)&mval);
3215 if (termch != '\n') termch = 0;
3216 scanhex((void *)&mask);
3220 for (a = mdest; a < mend; a += 4) {
3221 if (mread(a, val, 4) == 4
3222 && ((GETWORD(val) ^ mval) & mask) == 0) {
3223 printf("%.16x: %.16x\n", a, GETWORD(val));
3230 static unsigned long mskip = 0x1000;
3231 static unsigned long mlim = 0xffffffff;
3241 if (termch != '\n') termch = 0;
3243 if (termch != '\n') termch = 0;
3246 for (a = mdest; a < mlim; a += mskip) {
3247 ok = mread(a, &v, 1);
3249 printf("%.8x .. ", a);
3250 } else if (!ok && ook)
3251 printf("%.8lx\n", a - mskip);
3257 printf("%.8lx\n", a - mskip);
3260 static void show_task(struct task_struct *volatile tsk)
3262 unsigned int p_state = READ_ONCE(tsk->__state);
3266 * Cloned from kdb_task_state_char(), which is not entirely
3267 * appropriate for calling from xmon. This could be moved
3268 * to a common, generic, routine used by both.
3270 state = (p_state == TASK_RUNNING) ? 'R' :
3271 (p_state & TASK_UNINTERRUPTIBLE) ? 'D' :
3272 (p_state & TASK_STOPPED) ? 'T' :
3273 (p_state & TASK_TRACED) ? 'C' :
3274 (tsk->exit_state & EXIT_ZOMBIE) ? 'Z' :
3275 (tsk->exit_state & EXIT_DEAD) ? 'E' :
3276 (p_state & TASK_INTERRUPTIBLE) ? 'S' : '?';
3278 printf("%16px %16lx %16px %6d %6d %c %2d %s\n", tsk,
3279 tsk->thread.ksp, tsk->thread.regs,
3280 tsk->pid, rcu_dereference(tsk->parent)->pid,
3281 state, task_cpu(tsk),
3285 #ifdef CONFIG_PPC_BOOK3S_64
3286 static void format_pte(void *ptep, unsigned long pte)
3288 pte_t entry = __pte(pte);
3290 printf("ptep @ 0x%016lx = 0x%016lx\n", (unsigned long)ptep, pte);
3291 printf("Maps physical address = 0x%016lx\n", pte & PTE_RPN_MASK);
3293 printf("Flags = %s%s%s%s%s\n",
3294 pte_young(entry) ? "Accessed " : "",
3295 pte_dirty(entry) ? "Dirty " : "",
3296 pte_read(entry) ? "Read " : "",
3297 pte_write(entry) ? "Write " : "",
3298 pte_exec(entry) ? "Exec " : "");
3301 static void show_pte(unsigned long addr)
3303 unsigned long tskv = 0;
3304 struct task_struct *volatile tsk = NULL;
3305 struct mm_struct *volatile mm;
3312 if (!scanhex(&tskv))
3315 tsk = (struct task_struct *)tskv;
3320 mm = tsk->active_mm;
3322 if (setjmp(bus_error_jmp) != 0) {
3323 catch_memory_errors = 0;
3324 printf("*** Error dumping pte for task %px\n", tsk);
3328 catch_memory_errors = 1;
3332 pgdp = pgd_offset_k(addr);
3334 pgdp = pgd_offset(mm, addr);
3336 p4dp = p4d_offset(pgdp, addr);
3338 if (p4d_none(*p4dp)) {
3339 printf("No valid P4D\n");
3343 if (p4d_leaf(*p4dp)) {
3344 format_pte(p4dp, p4d_val(*p4dp));
3348 printf("p4dp @ 0x%px = 0x%016lx\n", p4dp, p4d_val(*p4dp));
3350 pudp = pud_offset(p4dp, addr);
3352 if (pud_none(*pudp)) {
3353 printf("No valid PUD\n");
3357 if (pud_leaf(*pudp)) {
3358 format_pte(pudp, pud_val(*pudp));
3362 printf("pudp @ 0x%px = 0x%016lx\n", pudp, pud_val(*pudp));
3364 pmdp = pmd_offset(pudp, addr);
3366 if (pmd_none(*pmdp)) {
3367 printf("No valid PMD\n");
3371 if (pmd_leaf(*pmdp)) {
3372 format_pte(pmdp, pmd_val(*pmdp));
3375 printf("pmdp @ 0x%px = 0x%016lx\n", pmdp, pmd_val(*pmdp));
3377 ptep = pte_offset_map(pmdp, addr);
3378 if (!ptep || pte_none(*ptep)) {
3381 printf("no valid PTE\n");
3385 format_pte(ptep, pte_val(*ptep));
3390 catch_memory_errors = 0;
3393 static void show_pte(unsigned long addr)
3395 printf("show_pte not yet implemented\n");
3397 #endif /* CONFIG_PPC_BOOK3S_64 */
3399 static void show_tasks(void)
3402 struct task_struct *volatile tsk = NULL;
3404 printf(" task_struct ->thread.ksp ->thread.regs PID PPID S P CMD\n");
3407 tsk = (struct task_struct *)tskv;
3409 if (setjmp(bus_error_jmp) != 0) {
3410 catch_memory_errors = 0;
3411 printf("*** Error dumping task %px\n", tsk);
3415 catch_memory_errors = 1;
3421 for_each_process(tsk)
3426 catch_memory_errors = 0;
3429 static void proccall(void)
3431 unsigned long args[8];
3434 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
3435 unsigned long, unsigned long, unsigned long,
3436 unsigned long, unsigned long, unsigned long);
3439 if (!scanhex(&adrs))
3443 for (i = 0; i < 8; ++i)
3445 for (i = 0; i < 8; ++i) {
3446 if (!scanhex(&args[i]) || termch == '\n')
3450 func = (callfunc_t) adrs;
3452 if (setjmp(bus_error_jmp) == 0) {
3453 catch_memory_errors = 1;
3455 ret = func(args[0], args[1], args[2], args[3],
3456 args[4], args[5], args[6], args[7]);
3458 printf("return value is 0x%lx\n", ret);
3460 printf("*** %x exception occurred\n", fault_except);
3462 catch_memory_errors = 0;
3465 /* Input scanning routines */
3476 while( c == ' ' || c == '\t' )
3482 static const char *regnames[N_PTREGS] = {
3483 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
3484 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
3485 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
3486 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
3487 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
3493 "trap", "dar", "dsisr", "res"
3497 scanhex(unsigned long *vp)
3504 /* parse register name */
3508 for (i = 0; i < sizeof(regname) - 1; ++i) {
3517 i = match_string(regnames, N_PTREGS, regname);
3519 printf("invalid register name '%%%s'\n", regname);
3522 if (xmon_regs == NULL) {
3523 printf("regs not available\n");
3526 *vp = ((unsigned long *)xmon_regs)[i];
3530 /* skip leading "0x" if any */
3544 } else if (c == '$') {
3546 for (i=0; i<63; i++) {
3548 if (isspace(c) || c == '\0') {
3556 if (setjmp(bus_error_jmp) == 0) {
3557 catch_memory_errors = 1;
3559 *vp = kallsyms_lookup_name(tmpstr);
3562 catch_memory_errors = 0;
3564 printf("unknown symbol '%s'\n", tmpstr);
3597 static int hexdigit(int c)
3599 if( '0' <= c && c <= '9' )
3601 if( 'A' <= c && c <= 'F' )
3602 return c - ('A' - 10);
3603 if( 'a' <= c && c <= 'f' )
3604 return c - ('a' - 10);
3609 getstring(char *s, int size)
3625 } while( c != ' ' && c != '\t' && c != '\n' );
3630 static char line[256];
3631 static char *lineptr;
3642 if (lineptr == NULL || *lineptr == 0) {
3643 if (xmon_gets(line, sizeof(line)) == NULL) {
3653 take_input(char *str)
3662 int type = inchar();
3663 unsigned long addr, cpu;
3664 void __percpu *ptr = NULL;
3665 static char tmp[64];
3670 xmon_print_symbol(addr, ": ", "\n");
3675 if (setjmp(bus_error_jmp) == 0) {
3676 catch_memory_errors = 1;
3678 addr = kallsyms_lookup_name(tmp);
3680 printf("%s: %lx\n", tmp, addr);
3682 printf("Symbol '%s' not found.\n", tmp);
3685 catch_memory_errors = 0;
3690 if (setjmp(bus_error_jmp) == 0) {
3691 catch_memory_errors = 1;
3693 ptr = (void __percpu *)kallsyms_lookup_name(tmp);
3698 ptr >= (void __percpu *)__per_cpu_start &&
3699 ptr < (void __percpu *)__per_cpu_end)
3701 if (scanhex(&cpu) && cpu < num_possible_cpus()) {
3702 addr = (unsigned long)per_cpu_ptr(ptr, cpu);
3704 cpu = raw_smp_processor_id();
3705 addr = (unsigned long)this_cpu_ptr(ptr);
3708 printf("%s for cpu 0x%lx: %lx\n", tmp, cpu, addr);
3710 printf("Percpu symbol '%s' not found.\n", tmp);
3713 catch_memory_errors = 0;
3720 /* Print an address in numeric and symbolic form (if possible) */
3721 static void xmon_print_symbol(unsigned long address, const char *mid,
3725 const char *volatile name = NULL;
3726 unsigned long offset, size;
3728 printf(REG, address);
3729 if (setjmp(bus_error_jmp) == 0) {
3730 catch_memory_errors = 1;
3732 name = kallsyms_lookup(address, &size, &offset, &modname,
3735 /* wait a little while to see if we get a machine check */
3739 catch_memory_errors = 0;
3742 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
3744 printf(" [%s]", modname);
3746 printf("%s", after);
3749 #ifdef CONFIG_PPC_64S_HASH_MMU
3750 void dump_segments(void)
3753 unsigned long esid,vsid;
3756 printf("SLB contents of cpu 0x%x\n", smp_processor_id());
3758 for (i = 0; i < mmu_slb_size; i++) {
3759 asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i));
3760 asm volatile("slbmfev %0,%1" : "=r" (vsid) : "r" (i));
3765 printf("%02d %016lx %016lx", i, esid, vsid);
3767 if (!(esid & SLB_ESID_V)) {
3772 llp = vsid & SLB_VSID_LLP;
3773 if (vsid & SLB_VSID_B_1T) {
3774 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
3776 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T,
3779 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
3781 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT,
3788 #ifdef CONFIG_PPC_BOOK3S_32
3789 void dump_segments(void)
3794 for (i = 0; i < 16; ++i)
3795 printf(" %x", mfsr(i << 28));
3801 static void dump_tlb_44x(void)
3805 for (i = 0; i < PPC44x_TLB_SIZE; i++) {
3806 unsigned long w0,w1,w2;
3807 asm volatile("tlbre %0,%1,0" : "=r" (w0) : "r" (i));
3808 asm volatile("tlbre %0,%1,1" : "=r" (w1) : "r" (i));
3809 asm volatile("tlbre %0,%1,2" : "=r" (w2) : "r" (i));
3810 printf("[%02x] %08lx %08lx %08lx ", i, w0, w1, w2);
3811 if (w0 & PPC44x_TLB_VALID) {
3812 printf("V %08lx -> %01lx%08lx %c%c%c%c%c",
3813 w0 & PPC44x_TLB_EPN_MASK,
3814 w1 & PPC44x_TLB_ERPN_MASK,
3815 w1 & PPC44x_TLB_RPN_MASK,
3816 (w2 & PPC44x_TLB_W) ? 'W' : 'w',
3817 (w2 & PPC44x_TLB_I) ? 'I' : 'i',
3818 (w2 & PPC44x_TLB_M) ? 'M' : 'm',
3819 (w2 & PPC44x_TLB_G) ? 'G' : 'g',
3820 (w2 & PPC44x_TLB_E) ? 'E' : 'e');
3825 #endif /* CONFIG_44x */
3827 #ifdef CONFIG_PPC_BOOK3E_64
3828 static void dump_tlb_book3e(void)
3832 int i, tlb, ntlbs, pidsz, lpidsz, rasz;
3834 static const char *pgsz_names[] = {
3869 /* Gather some infos about the MMU */
3870 mmucfg = mfspr(SPRN_MMUCFG);
3871 mmu_version = (mmucfg & 3) + 1;
3872 ntlbs = ((mmucfg >> 2) & 3) + 1;
3873 pidsz = ((mmucfg >> 6) & 0x1f) + 1;
3874 lpidsz = (mmucfg >> 24) & 0xf;
3875 rasz = (mmucfg >> 16) & 0x7f;
3876 printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n",
3877 mmu_version, ntlbs, pidsz, lpidsz, rasz);
3878 ramask = (1ull << rasz) - 1;
3880 for (tlb = 0; tlb < ntlbs; tlb++) {
3882 int nent, assoc, new_cc = 1;
3883 printf("TLB %d:\n------\n", tlb);
3886 tlbcfg = mfspr(SPRN_TLB0CFG);
3889 tlbcfg = mfspr(SPRN_TLB1CFG);
3892 tlbcfg = mfspr(SPRN_TLB2CFG);
3895 tlbcfg = mfspr(SPRN_TLB3CFG);
3898 printf("Unsupported TLB number !\n");
3901 nent = tlbcfg & 0xfff;
3902 assoc = (tlbcfg >> 24) & 0xff;
3903 for (i = 0; i < nent; i++) {
3904 u32 mas0 = MAS0_TLBSEL(tlb);
3905 u32 mas1 = MAS1_TSIZE(BOOK3E_PAGESZ_4K);
3908 int esel = i, cc = i;
3916 mas0 |= MAS0_ESEL(esel);
3917 mtspr(SPRN_MAS0, mas0);
3918 mtspr(SPRN_MAS1, mas1);
3919 mtspr(SPRN_MAS2, mas2);
3920 asm volatile("tlbre 0,0,0" : : : "memory");
3921 mas1 = mfspr(SPRN_MAS1);
3922 mas2 = mfspr(SPRN_MAS2);
3923 mas7_mas3 = mfspr(SPRN_MAS7_MAS3);
3924 if (assoc && (i % assoc) == 0)
3926 if (!(mas1 & MAS1_VALID))
3929 printf("%04x- ", i);
3931 printf("%04x-%c", cc, 'A' + esel);
3933 printf(" |%c", 'A' + esel);
3935 printf(" %016llx %04x %s %c%c AS%c",
3937 (mas1 >> 16) & 0x3fff,
3938 pgsz_names[(mas1 >> 7) & 0x1f],
3939 mas1 & MAS1_IND ? 'I' : ' ',
3940 mas1 & MAS1_IPROT ? 'P' : ' ',
3941 mas1 & MAS1_TS ? '1' : '0');
3942 printf(" %c%c%c%c%c%c%c",
3943 mas2 & MAS2_X0 ? 'a' : ' ',
3944 mas2 & MAS2_X1 ? 'v' : ' ',
3945 mas2 & MAS2_W ? 'w' : ' ',
3946 mas2 & MAS2_I ? 'i' : ' ',
3947 mas2 & MAS2_M ? 'm' : ' ',
3948 mas2 & MAS2_G ? 'g' : ' ',
3949 mas2 & MAS2_E ? 'e' : ' ');
3950 printf(" %016llx", mas7_mas3 & ramask & ~0x7ffull);
3951 if (mas1 & MAS1_IND)
3953 pgsz_names[(mas7_mas3 >> 1) & 0x1f]);
3955 printf(" U%c%c%c S%c%c%c\n",
3956 mas7_mas3 & MAS3_UX ? 'x' : ' ',
3957 mas7_mas3 & MAS3_UW ? 'w' : ' ',
3958 mas7_mas3 & MAS3_UR ? 'r' : ' ',
3959 mas7_mas3 & MAS3_SX ? 'x' : ' ',
3960 mas7_mas3 & MAS3_SW ? 'w' : ' ',
3961 mas7_mas3 & MAS3_SR ? 'r' : ' ');
3965 #endif /* CONFIG_PPC_BOOK3E_64 */
3967 static void xmon_init(int enable)
3971 __debugger_ipi = xmon_ipi;
3972 __debugger_bpt = xmon_bpt;
3973 __debugger_sstep = xmon_sstep;
3974 __debugger_iabr_match = xmon_iabr_match;
3975 __debugger_break_match = xmon_break_match;
3976 __debugger_fault_handler = xmon_fault_handler;
3979 __debugger_ipi = NULL;
3980 __debugger_bpt = NULL;
3981 __debugger_sstep = NULL;
3982 __debugger_iabr_match = NULL;
3983 __debugger_break_match = NULL;
3984 __debugger_fault_handler = NULL;
3988 #ifdef CONFIG_MAGIC_SYSRQ
3989 static void sysrq_handle_xmon(u8 key)
3991 if (xmon_is_locked_down()) {
3996 /* ensure xmon is enabled */
3998 debugger(get_irq_regs());
4003 static const struct sysrq_key_op sysrq_xmon_op = {
4004 .handler = sysrq_handle_xmon,
4005 .help_msg = "xmon(x)",
4006 .action_msg = "Entering xmon",
4009 static int __init setup_xmon_sysrq(void)
4011 register_sysrq_key('x', &sysrq_xmon_op);
4014 device_initcall(setup_xmon_sysrq);
4015 #endif /* CONFIG_MAGIC_SYSRQ */
4017 static void clear_all_bpt(void)
4021 /* clear/unpatch all breakpoints */
4025 /* Disable all breakpoints */
4026 for (i = 0; i < NBPTS; ++i)
4027 bpts[i].enabled = 0;
4029 /* Clear any data or iabr breakpoints */
4031 for (i = 0; i < nr_wp_slots(); i++)
4032 dabr[i].enabled = 0;
4035 #ifdef CONFIG_DEBUG_FS
4036 static int xmon_dbgfs_set(void *data, u64 val)
4041 /* make sure all breakpoints removed when disabling */
4045 printf("xmon: All breakpoints cleared\n");
4046 release_output_lock();
4052 static int xmon_dbgfs_get(void *data, u64 *val)
4058 DEFINE_SIMPLE_ATTRIBUTE(xmon_dbgfs_ops, xmon_dbgfs_get,
4059 xmon_dbgfs_set, "%llu\n");
4061 static int __init setup_xmon_dbgfs(void)
4063 debugfs_create_file("xmon", 0600, arch_debugfs_dir, NULL,
4067 device_initcall(setup_xmon_dbgfs);
4068 #endif /* CONFIG_DEBUG_FS */
4070 static int xmon_early __initdata;
4072 static int __init early_parse_xmon(char *p)
4074 if (xmon_is_locked_down()) {
4078 } else if (!p || strncmp(p, "early", 5) == 0) {
4079 /* just "xmon" is equivalent to "xmon=early" */
4083 } else if (strncmp(p, "on", 2) == 0) {
4086 } else if (strncmp(p, "rw", 2) == 0) {
4090 } else if (strncmp(p, "ro", 2) == 0) {
4094 } else if (strncmp(p, "off", 3) == 0)
4101 early_param("xmon", early_parse_xmon);
4103 void __init xmon_setup(void)
4111 #ifdef CONFIG_SPU_BASE
4115 u64 saved_mfc_sr1_RW;
4116 u32 saved_spu_runcntl_RW;
4117 unsigned long dump_addr;
4121 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
4123 static struct spu_info spu_info[XMON_NUM_SPUS];
4125 void __init xmon_register_spus(struct list_head *list)
4129 list_for_each_entry(spu, list, full_list) {
4130 if (spu->number >= XMON_NUM_SPUS) {
4135 spu_info[spu->number].spu = spu;
4136 spu_info[spu->number].stopped_ok = 0;
4137 spu_info[spu->number].dump_addr = (unsigned long)
4138 spu_info[spu->number].spu->local_store;
4142 static void stop_spus(void)
4148 for (i = 0; i < XMON_NUM_SPUS; i++) {
4149 if (!spu_info[i].spu)
4152 if (setjmp(bus_error_jmp) == 0) {
4153 catch_memory_errors = 1;
4156 spu = spu_info[i].spu;
4158 spu_info[i].saved_spu_runcntl_RW =
4159 in_be32(&spu->problem->spu_runcntl_RW);
4161 tmp = spu_mfc_sr1_get(spu);
4162 spu_info[i].saved_mfc_sr1_RW = tmp;
4164 tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
4165 spu_mfc_sr1_set(spu, tmp);
4170 spu_info[i].stopped_ok = 1;
4172 printf("Stopped spu %.2d (was %s)\n", i,
4173 spu_info[i].saved_spu_runcntl_RW ?
4174 "running" : "stopped");
4176 catch_memory_errors = 0;
4177 printf("*** Error stopping spu %.2d\n", i);
4179 catch_memory_errors = 0;
4183 static void restart_spus(void)
4188 for (i = 0; i < XMON_NUM_SPUS; i++) {
4189 if (!spu_info[i].spu)
4192 if (!spu_info[i].stopped_ok) {
4193 printf("*** Error, spu %d was not successfully stopped"
4194 ", not restarting\n", i);
4198 if (setjmp(bus_error_jmp) == 0) {
4199 catch_memory_errors = 1;
4202 spu = spu_info[i].spu;
4203 spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
4204 out_be32(&spu->problem->spu_runcntl_RW,
4205 spu_info[i].saved_spu_runcntl_RW);
4210 printf("Restarted spu %.2d\n", i);
4212 catch_memory_errors = 0;
4213 printf("*** Error restarting spu %.2d\n", i);
4215 catch_memory_errors = 0;
4219 #define DUMP_WIDTH 23
4220 #define DUMP_VALUE(format, field, value) \
4222 if (setjmp(bus_error_jmp) == 0) { \
4223 catch_memory_errors = 1; \
4225 printf(" %-*s = "format"\n", DUMP_WIDTH, \
4230 catch_memory_errors = 0; \
4231 printf(" %-*s = *** Error reading field.\n", \
4232 DUMP_WIDTH, #field); \
4234 catch_memory_errors = 0; \
4237 #define DUMP_FIELD(obj, format, field) \
4238 DUMP_VALUE(format, field, obj->field)
4240 static void dump_spu_fields(struct spu *spu)
4242 printf("Dumping spu fields at address %p:\n", spu);
4244 DUMP_FIELD(spu, "0x%x", number);
4245 DUMP_FIELD(spu, "%s", name);
4246 DUMP_FIELD(spu, "0x%lx", local_store_phys);
4247 DUMP_FIELD(spu, "0x%p", local_store);
4248 DUMP_FIELD(spu, "0x%lx", ls_size);
4249 DUMP_FIELD(spu, "0x%x", node);
4250 DUMP_FIELD(spu, "0x%lx", flags);
4251 DUMP_FIELD(spu, "%llu", class_0_pending);
4252 DUMP_FIELD(spu, "0x%llx", class_0_dar);
4253 DUMP_FIELD(spu, "0x%llx", class_1_dar);
4254 DUMP_FIELD(spu, "0x%llx", class_1_dsisr);
4255 DUMP_FIELD(spu, "0x%x", irqs[0]);
4256 DUMP_FIELD(spu, "0x%x", irqs[1]);
4257 DUMP_FIELD(spu, "0x%x", irqs[2]);
4258 DUMP_FIELD(spu, "0x%x", slb_replace);
4259 DUMP_FIELD(spu, "%d", pid);
4260 DUMP_FIELD(spu, "0x%p", mm);
4261 DUMP_FIELD(spu, "0x%p", ctx);
4262 DUMP_FIELD(spu, "0x%p", rq);
4263 DUMP_FIELD(spu, "0x%llx", timestamp);
4264 DUMP_FIELD(spu, "0x%lx", problem_phys);
4265 DUMP_FIELD(spu, "0x%p", problem);
4266 DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
4267 in_be32(&spu->problem->spu_runcntl_RW));
4268 DUMP_VALUE("0x%x", problem->spu_status_R,
4269 in_be32(&spu->problem->spu_status_R));
4270 DUMP_VALUE("0x%x", problem->spu_npc_RW,
4271 in_be32(&spu->problem->spu_npc_RW));
4272 DUMP_FIELD(spu, "0x%p", priv2);
4273 DUMP_FIELD(spu, "0x%p", pdata);
4276 static int spu_inst_dump(unsigned long adr, long count, int praddr)
4278 return generic_inst_dump(adr, count, praddr, print_insn_spu);
4281 static void dump_spu_ls(unsigned long num, int subcmd)
4283 unsigned long offset, addr, ls_addr;
4285 if (setjmp(bus_error_jmp) == 0) {
4286 catch_memory_errors = 1;
4288 ls_addr = (unsigned long)spu_info[num].spu->local_store;
4292 catch_memory_errors = 0;
4293 printf("*** Error: accessing spu info for spu %ld\n", num);
4296 catch_memory_errors = 0;
4298 if (scanhex(&offset))
4299 addr = ls_addr + offset;
4301 addr = spu_info[num].dump_addr;
4303 if (addr >= ls_addr + LS_SIZE) {
4304 printf("*** Error: address outside of local store\n");
4310 addr += spu_inst_dump(addr, 16, 1);
4320 spu_info[num].dump_addr = addr;
4323 static int do_spu_cmd(void)
4325 static unsigned long num = 0;
4326 int cmd, subcmd = 0;
4338 if (isxdigit(subcmd) || subcmd == '\n')
4343 if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
4344 printf("*** Error: invalid spu number\n");
4350 dump_spu_fields(spu_info[num].spu);
4353 dump_spu_ls(num, subcmd);
4364 #else /* ! CONFIG_SPU_BASE */
4365 static int do_spu_cmd(void)