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>
30 #include <asm/debugfs.h>
31 #include <asm/ptrace.h>
33 #include <asm/string.h>
35 #include <asm/machdep.h>
37 #include <asm/processor.h>
38 #include <asm/pgtable.h>
40 #include <asm/mmu_context.h>
41 #include <asm/plpar_wrappers.h>
42 #include <asm/cputable.h>
44 #include <asm/sstep.h>
45 #include <asm/irq_regs.h>
47 #include <asm/spu_priv1.h>
48 #include <asm/setjmp.h>
50 #include <asm/debug.h>
51 #include <asm/hw_breakpoint.h>
54 #include <asm/firmware.h>
55 #include <asm/code-patching.h>
56 #include <asm/sections.h>
59 #include <asm/hvcall.h>
67 static cpumask_t cpus_in_xmon = CPU_MASK_NONE;
68 static unsigned long xmon_taken = 1;
69 static int xmon_owner;
73 #endif /* CONFIG_SMP */
75 #ifdef CONFIG_PPC_PSERIES
76 static int set_indicator_token = RTAS_UNKNOWN_SERVICE;
78 static unsigned long in_xmon __read_mostly = 0;
79 static int xmon_on = IS_ENABLED(CONFIG_XMON_DEFAULT);
80 static bool xmon_is_ro = IS_ENABLED(CONFIG_XMON_DEFAULT_RO_MODE);
82 static unsigned long adrs;
84 #define MAX_DUMP (64 * 1024)
85 static unsigned long ndump = 64;
86 #define MAX_IDUMP (MAX_DUMP >> 2)
87 static unsigned long nidump = 16;
88 static unsigned long ncsum = 4096;
90 static char tmpstr[128];
91 static int tracing_enabled;
93 static long bus_error_jmp[JMP_BUF_LEN];
94 static int catch_memory_errors;
95 static int catch_spr_faults;
96 static long *xmon_fault_jmp[NR_CPUS];
98 /* Breakpoint stuff */
100 unsigned long address;
101 unsigned int instr[2];
107 /* Bits in bpt.enabled */
113 static struct bpt bpts[NBPTS];
114 static struct bpt dabr;
115 static struct bpt *iabr;
116 static unsigned bpinstr = 0x7fe00008; /* trap */
118 #define BP_NUM(bp) ((bp) - bpts + 1)
121 static int cmds(struct pt_regs *);
122 static int mread(unsigned long, void *, int);
123 static int mwrite(unsigned long, void *, int);
124 static int handle_fault(struct pt_regs *);
125 static void byterev(unsigned char *, int);
126 static void memex(void);
127 static int bsesc(void);
128 static void dump(void);
129 static void show_pte(unsigned long);
130 static void prdump(unsigned long, long);
131 static int ppc_inst_dump(unsigned long, long, int);
132 static void dump_log_buf(void);
134 #ifdef CONFIG_PPC_POWERNV
135 static void dump_opal_msglog(void);
137 static inline void dump_opal_msglog(void)
139 printf("Machine is not running OPAL firmware.\n");
143 static void backtrace(struct pt_regs *);
144 static void excprint(struct pt_regs *);
145 static void prregs(struct pt_regs *);
146 static void memops(int);
147 static void memlocate(void);
148 static void memzcan(void);
149 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
151 int scanhex(unsigned long *valp);
152 static void scannl(void);
153 static int hexdigit(int);
154 void getstring(char *, int);
155 static void flush_input(void);
156 static int inchar(void);
157 static void take_input(char *);
158 static int read_spr(int, unsigned long *);
159 static void write_spr(int, unsigned long);
160 static void super_regs(void);
161 static void remove_bpts(void);
162 static void insert_bpts(void);
163 static void remove_cpu_bpts(void);
164 static void insert_cpu_bpts(void);
165 static struct bpt *at_breakpoint(unsigned long pc);
166 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
167 static int do_step(struct pt_regs *);
168 static void bpt_cmds(void);
169 static void cacheflush(void);
170 static int cpu_cmd(void);
171 static void csum(void);
172 static void bootcmds(void);
173 static void proccall(void);
174 static void show_tasks(void);
175 void dump_segments(void);
176 static void symbol_lookup(void);
177 static void xmon_show_stack(unsigned long sp, unsigned long lr,
179 static void xmon_print_symbol(unsigned long address, const char *mid,
181 static const char *getvecname(unsigned long vec);
183 static int do_spu_cmd(void);
186 static void dump_tlb_44x(void);
188 #ifdef CONFIG_PPC_BOOK3E
189 static void dump_tlb_book3e(void);
192 static void clear_all_bpt(void);
200 #ifdef __LITTLE_ENDIAN__
201 #define GETWORD(v) (((v)[3] << 24) + ((v)[2] << 16) + ((v)[1] << 8) + (v)[0])
203 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
206 static const char *xmon_ro_msg = "Operation disabled: xmon in read-only mode\n";
208 static char *help_string = "\
210 b show breakpoints\n\
211 bd set data breakpoint\n\
212 bi set instruction breakpoint\n\
213 bc clear breakpoint\n"
216 c print cpus stopped in xmon\n\
217 c# try to switch to cpu number h (in hex)\n"
222 d1 dump 1 byte values\n\
223 d2 dump 2 byte values\n\
224 d4 dump 4 byte values\n\
225 d8 dump 8 byte values\n\
226 di dump instructions\n\
227 df dump float values\n\
228 dd dump double values\n\
229 dl dump the kernel log buffer\n"
230 #ifdef CONFIG_PPC_POWERNV
232 do dump the OPAL message log\n"
236 dp[#] dump paca for current cpu, or cpu #\n\
237 dpa dump paca for all possible cpus\n"
240 dr dump stream of raw bytes\n\
241 dv dump virtual address translation \n\
242 dt dump the tracing buffers (uses printk)\n\
243 dtc dump the tracing buffers for current CPU (uses printk)\n\
245 #ifdef CONFIG_PPC_POWERNV
246 " dx# dump xive on CPU #\n\
247 dxi# dump xive irq state #\n\
248 dxa dump xive on all CPUs\n"
250 " e print exception information\n\
252 la lookup symbol+offset of specified address\n\
253 ls lookup address of specified symbol\n\
254 lp s [#] lookup address of percpu symbol s for current cpu, or cpu #\n\
255 m examine/change memory\n\
256 mm move a block of memory\n\
257 ms set a block of memory\n\
258 md compare two blocks of memory\n\
259 ml locate a block of memory\n\
260 mz zero a block of memory\n\
261 mi show information about memory allocation\n\
262 p call a procedure\n\
263 P list processes/tasks\n\
266 #ifdef CONFIG_SPU_BASE
267 " ss stop execution on all spus\n\
268 sr restore execution on stopped spus\n\
269 sf # dump spu fields for spu # (in hex)\n\
270 sd # dump spu local store for spu # (in hex)\n\
271 sdi # disassemble spu local store for spu # (in hex)\n"
273 " S print special registers\n\
276 Sw #v write v to SPR #\n\
278 x exit monitor and recover\n\
279 X exit monitor and don't recover\n"
280 #if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_BOOK3E)
281 " u dump segment table or SLB\n"
282 #elif defined(CONFIG_PPC_BOOK3S_32)
283 " u dump segment registers\n"
284 #elif defined(CONFIG_44x) || defined(CONFIG_PPC_BOOK3E)
287 " U show uptime information\n"
289 " # n limit output to n lines per page (for dp, dpa, dl)\n"
294 #ifdef CONFIG_SECURITY
295 static bool xmon_is_locked_down(void)
297 static bool lockdown;
300 lockdown = !!security_locked_down(LOCKDOWN_XMON_RW);
302 printf("xmon: Disabled due to kernel lockdown\n");
308 xmon_is_ro = !!security_locked_down(LOCKDOWN_XMON_WR);
310 printf("xmon: Read-only due to kernel lockdown\n");
315 #else /* CONFIG_SECURITY */
316 static inline bool xmon_is_locked_down(void)
322 static struct pt_regs *xmon_regs;
324 static inline void sync(void)
326 asm volatile("sync; isync");
329 static inline void store_inst(void *p)
331 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
334 static inline void cflush(void *p)
336 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
339 static inline void cinval(void *p)
341 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
345 * write_ciabr() - write the CIABR SPR
346 * @ciabr: The value to write.
348 * This function writes a value to the CIARB register either directly
349 * through mtspr instruction if the kernel is in HV privilege mode or
350 * call a hypervisor function to achieve the same in case the kernel
351 * is in supervisor privilege mode.
353 static void write_ciabr(unsigned long ciabr)
355 if (!cpu_has_feature(CPU_FTR_ARCH_207S))
358 if (cpu_has_feature(CPU_FTR_HVMODE)) {
359 mtspr(SPRN_CIABR, ciabr);
362 plpar_set_ciabr(ciabr);
366 * set_ciabr() - set the CIABR
367 * @addr: The value to set.
369 * This function sets the correct privilege value into the the HW
370 * breakpoint address before writing it up in the CIABR register.
372 static void set_ciabr(unsigned long addr)
376 if (cpu_has_feature(CPU_FTR_HVMODE))
377 addr |= CIABR_PRIV_HYPER;
379 addr |= CIABR_PRIV_SUPER;
384 * Disable surveillance (the service processor watchdog function)
385 * while we are in xmon.
386 * XXX we should re-enable it when we leave. :)
388 #define SURVEILLANCE_TOKEN 9000
390 static inline void disable_surveillance(void)
392 #ifdef CONFIG_PPC_PSERIES
393 /* Since this can't be a module, args should end up below 4GB. */
394 static struct rtas_args args;
397 * At this point we have got all the cpus we can into
398 * xmon, so there is hopefully no other cpu calling RTAS
399 * at the moment, even though we don't take rtas.lock.
400 * If we did try to take rtas.lock there would be a
401 * real possibility of deadlock.
403 if (set_indicator_token == RTAS_UNKNOWN_SERVICE)
406 rtas_call_unlocked(&args, set_indicator_token, 3, 1, NULL,
407 SURVEILLANCE_TOKEN, 0, 0);
409 #endif /* CONFIG_PPC_PSERIES */
413 static int xmon_speaker;
415 static void get_output_lock(void)
417 int me = smp_processor_id() + 0x100;
418 int last_speaker = 0, prev;
421 if (xmon_speaker == me)
425 last_speaker = cmpxchg(&xmon_speaker, 0, me);
426 if (last_speaker == 0)
430 * Wait a full second for the lock, we might be on a slow
431 * console, but check every 100us.
434 while (xmon_speaker == last_speaker) {
440 /* hostile takeover */
441 prev = cmpxchg(&xmon_speaker, last_speaker, me);
442 if (prev == last_speaker)
449 static void release_output_lock(void)
454 int cpus_are_in_xmon(void)
456 return !cpumask_empty(&cpus_in_xmon);
459 static bool wait_for_other_cpus(int ncpus)
461 unsigned long timeout;
463 /* We wait for 2s, which is a metric "little while" */
464 for (timeout = 20000; timeout != 0; --timeout) {
465 if (cpumask_weight(&cpus_in_xmon) >= ncpus)
473 #else /* CONFIG_SMP */
474 static inline void get_output_lock(void) {}
475 static inline void release_output_lock(void) {}
478 static inline int unrecoverable_excp(struct pt_regs *regs)
480 #if defined(CONFIG_4xx) || defined(CONFIG_PPC_BOOK3E)
481 /* We have no MSR_RI bit on 4xx or Book3e, so we simply return false */
484 return ((regs->msr & MSR_RI) == 0);
488 static int xmon_core(struct pt_regs *regs, int fromipi)
492 long recurse_jmp[JMP_BUF_LEN];
494 unsigned long offset;
501 local_irq_save(flags);
504 locked_down = xmon_is_locked_down();
507 tracing_enabled = tracing_is_on();
511 bp = in_breakpoint_table(regs->nip, &offset);
513 regs->nip = bp->address + offset;
514 atomic_dec(&bp->ref_count);
520 cpu = smp_processor_id();
521 if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
523 * We catch SPR read/write faults here because the 0x700, 0xf60
524 * etc. handlers don't call debugger_fault_handler().
526 if (catch_spr_faults)
527 longjmp(bus_error_jmp, 1);
530 printf("cpu 0x%x: Exception %lx %s in xmon, "
531 "returning to main loop\n",
532 cpu, regs->trap, getvecname(TRAP(regs)));
533 release_output_lock();
534 longjmp(xmon_fault_jmp[cpu], 1);
537 if (setjmp(recurse_jmp) != 0) {
538 if (!in_xmon || !xmon_gate) {
540 printf("xmon: WARNING: bad recursive fault "
541 "on cpu 0x%x\n", cpu);
542 release_output_lock();
545 secondary = !(xmon_taken && cpu == xmon_owner);
549 xmon_fault_jmp[cpu] = recurse_jmp;
552 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT))
553 bp = at_breakpoint(regs->nip);
554 if (bp || unrecoverable_excp(regs))
562 printf("cpu 0x%x stopped at breakpoint 0x%tx (",
564 xmon_print_symbol(regs->nip, " ", ")\n");
566 if (unrecoverable_excp(regs))
567 printf("WARNING: exception is not recoverable, "
569 release_output_lock();
572 cpumask_set_cpu(cpu, &cpus_in_xmon);
577 while (secondary && !xmon_gate) {
583 secondary = test_and_set_bit(0, &in_xmon);
586 touch_nmi_watchdog();
590 if (!secondary && !xmon_gate) {
591 /* we are the first cpu to come in */
592 /* interrupt other cpu(s) */
593 int ncpus = num_online_cpus();
599 * A system reset (trap == 0x100) can be triggered on
600 * all CPUs, so when we come in via 0x100 try waiting
601 * for the other CPUs to come in before we send the
602 * debugger break (IPI). This is similar to
603 * crash_kexec_secondary().
605 if (TRAP(regs) != 0x100 || !wait_for_other_cpus(ncpus))
606 smp_send_debugger_break();
608 wait_for_other_cpus(ncpus);
611 disable_surveillance();
614 /* for breakpoint or single step, print curr insn */
615 if (bp || TRAP(regs) == 0xd00)
616 ppc_inst_dump(regs->nip, 1, 0);
617 printf("enter ? for help\n");
623 touch_nmi_watchdog();
630 if (cpu == xmon_owner) {
631 if (!test_and_set_bit(0, &xmon_taken)) {
637 while (cpu == xmon_owner)
641 touch_nmi_watchdog();
645 if (locked_down || cmd != 0) {
653 /* have switched to some other cpu */
658 cpumask_clear_cpu(cpu, &cpus_in_xmon);
659 xmon_fault_jmp[cpu] = NULL;
661 /* UP is simple... */
663 printf("Exception %lx %s in xmon, returning to main loop\n",
664 regs->trap, getvecname(TRAP(regs)));
665 longjmp(xmon_fault_jmp[0], 1);
667 if (setjmp(recurse_jmp) == 0) {
668 xmon_fault_jmp[0] = recurse_jmp;
672 bp = at_breakpoint(regs->nip);
674 printf("Stopped at breakpoint %tx (", BP_NUM(bp));
675 xmon_print_symbol(regs->nip, " ", ")\n");
677 if (unrecoverable_excp(regs))
678 printf("WARNING: exception is not recoverable, "
681 disable_surveillance();
683 /* for breakpoint or single step, print current insn */
684 if (bp || TRAP(regs) == 0xd00)
685 ppc_inst_dump(regs->nip, 1, 0);
686 printf("enter ? for help\n");
698 if (regs->msr & MSR_DE) {
699 bp = at_breakpoint(regs->nip);
701 regs->nip = (unsigned long) &bp->instr[0];
702 atomic_inc(&bp->ref_count);
706 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
707 bp = at_breakpoint(regs->nip);
709 int stepped = emulate_step(regs, bp->instr[0]);
711 regs->nip = (unsigned long) &bp->instr[0];
712 atomic_inc(&bp->ref_count);
713 } else if (stepped < 0) {
714 printf("Couldn't single-step %s instruction\n",
715 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
725 touch_nmi_watchdog();
726 local_irq_restore(flags);
728 return cmd != 'X' && cmd != EOF;
731 int xmon(struct pt_regs *excp)
736 ppc_save_regs(®s);
740 return xmon_core(excp, 0);
744 irqreturn_t xmon_irq(int irq, void *d)
747 local_irq_save(flags);
748 printf("Keyboard interrupt\n");
749 xmon(get_irq_regs());
750 local_irq_restore(flags);
754 static int xmon_bpt(struct pt_regs *regs)
757 unsigned long offset;
759 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
762 /* Are we at the trap at bp->instr[1] for some bp? */
763 bp = in_breakpoint_table(regs->nip, &offset);
764 if (bp != NULL && offset == 4) {
765 regs->nip = bp->address + 4;
766 atomic_dec(&bp->ref_count);
770 /* Are we at a breakpoint? */
771 bp = at_breakpoint(regs->nip);
780 static int xmon_sstep(struct pt_regs *regs)
788 static int xmon_break_match(struct pt_regs *regs)
790 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
792 if (dabr.enabled == 0)
798 static int xmon_iabr_match(struct pt_regs *regs)
800 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
808 static int xmon_ipi(struct pt_regs *regs)
811 if (in_xmon && !cpumask_test_cpu(smp_processor_id(), &cpus_in_xmon))
817 static int xmon_fault_handler(struct pt_regs *regs)
820 unsigned long offset;
822 if (in_xmon && catch_memory_errors)
823 handle_fault(regs); /* doesn't return */
825 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
826 bp = in_breakpoint_table(regs->nip, &offset);
828 regs->nip = bp->address + offset;
829 atomic_dec(&bp->ref_count);
836 /* Force enable xmon if not already enabled */
837 static inline void force_enable_xmon(void)
839 /* Enable xmon hooks if needed */
841 printf("xmon: Enabling debugger hooks\n");
846 static struct bpt *at_breakpoint(unsigned long pc)
852 for (i = 0; i < NBPTS; ++i, ++bp)
853 if (bp->enabled && pc == bp->address)
858 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
862 off = nip - (unsigned long) bpts;
863 if (off >= sizeof(bpts))
865 off %= sizeof(struct bpt);
866 if (off != offsetof(struct bpt, instr[0])
867 && off != offsetof(struct bpt, instr[1]))
869 *offp = off - offsetof(struct bpt, instr[0]);
870 return (struct bpt *) (nip - off);
873 static struct bpt *new_breakpoint(unsigned long a)
878 bp = at_breakpoint(a);
882 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
883 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
885 bp->instr[1] = bpinstr;
886 store_inst(&bp->instr[1]);
891 printf("Sorry, no free breakpoints. Please clear one first.\n");
895 static void insert_bpts(void)
901 for (i = 0; i < NBPTS; ++i, ++bp) {
902 if ((bp->enabled & (BP_TRAP|BP_CIABR)) == 0)
904 if (mread(bp->address, &bp->instr[0], 4) != 4) {
905 printf("Couldn't read instruction at %lx, "
906 "disabling breakpoint there\n", bp->address);
910 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
911 printf("Breakpoint at %lx is on an mtmsrd or rfid "
912 "instruction, disabling it\n", bp->address);
916 store_inst(&bp->instr[0]);
917 if (bp->enabled & BP_CIABR)
919 if (patch_instruction((unsigned int *)bp->address,
921 printf("Couldn't write instruction at %lx, "
922 "disabling breakpoint there\n", bp->address);
923 bp->enabled &= ~BP_TRAP;
926 store_inst((void *)bp->address);
930 static void insert_cpu_bpts(void)
932 struct arch_hw_breakpoint brk;
935 brk.address = dabr.address;
936 brk.type = (dabr.enabled & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL;
937 brk.len = DABR_MAX_LEN;
938 __set_breakpoint(&brk);
942 set_ciabr(iabr->address);
945 static void remove_bpts(void)
952 for (i = 0; i < NBPTS; ++i, ++bp) {
953 if ((bp->enabled & (BP_TRAP|BP_CIABR)) != BP_TRAP)
955 if (mread(bp->address, &instr, 4) == 4
957 && patch_instruction(
958 (unsigned int *)bp->address, bp->instr[0]) != 0)
959 printf("Couldn't remove breakpoint at %lx\n",
962 store_inst((void *)bp->address);
966 static void remove_cpu_bpts(void)
968 hw_breakpoint_disable();
972 /* Based on uptime_proc_show(). */
976 struct timespec64 uptime;
978 if (setjmp(bus_error_jmp) == 0) {
979 catch_memory_errors = 1;
982 ktime_get_coarse_boottime_ts64(&uptime);
983 printf("Uptime: %lu.%.2lu seconds\n", (unsigned long)uptime.tv_sec,
984 ((unsigned long)uptime.tv_nsec / (NSEC_PER_SEC/100)));
989 catch_memory_errors = 0;
992 static void set_lpp_cmd(void)
996 if (!scanhex(&lpp)) {
997 printf("Invalid number.\n");
1000 xmon_set_pagination_lpp(lpp);
1002 /* Command interpreting routine */
1003 static char *last_cmd;
1006 cmds(struct pt_regs *excp)
1013 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1017 printf("%x:", smp_processor_id());
1018 #endif /* CONFIG_SMP */
1024 if (last_cmd == NULL)
1026 take_input(last_cmd);
1044 printf(xmon_ro_msg);
1064 prregs(excp); /* print regs */
1079 if (do_spu_cmd() == 0)
1086 if (tracing_enabled)
1090 printf(" <no input ...>\n");
1094 xmon_puts(help_string);
1114 printf(xmon_ro_msg);
1122 #ifdef CONFIG_PPC_BOOK3S
1126 #elif defined(CONFIG_44x)
1130 #elif defined(CONFIG_PPC_BOOK3E)
1139 printf("Unrecognized command: ");
1141 if (' ' < cmd && cmd <= '~')
1144 printf("\\x%x", cmd);
1146 } while (cmd != '\n');
1147 printf(" (type ? for help)\n");
1154 static int do_step(struct pt_regs *regs)
1156 regs->msr |= MSR_DE;
1157 mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
1162 * Step a single instruction.
1163 * Some instructions we emulate, others we execute with MSR_SE set.
1165 static int do_step(struct pt_regs *regs)
1170 force_enable_xmon();
1171 /* check we are in 64-bit kernel mode, translation enabled */
1172 if ((regs->msr & (MSR_64BIT|MSR_PR|MSR_IR)) == (MSR_64BIT|MSR_IR)) {
1173 if (mread(regs->nip, &instr, 4) == 4) {
1174 stepped = emulate_step(regs, instr);
1176 printf("Couldn't single-step %s instruction\n",
1177 (IS_RFID(instr)? "rfid": "mtmsrd"));
1181 regs->trap = 0xd00 | (regs->trap & 1);
1182 printf("stepped to ");
1183 xmon_print_symbol(regs->nip, " ", "\n");
1184 ppc_inst_dump(regs->nip, 1, 0);
1189 regs->msr |= MSR_SE;
1194 static void bootcmds(void)
1202 ppc_md.restart(tmp);
1203 } else if (cmd == 'h') {
1205 } else if (cmd == 'p') {
1211 static int cpu_cmd(void)
1214 unsigned long cpu, first_cpu, last_cpu;
1217 if (!scanhex(&cpu)) {
1218 /* print cpus waiting or in xmon */
1219 printf("cpus stopped:");
1220 last_cpu = first_cpu = NR_CPUS;
1221 for_each_possible_cpu(cpu) {
1222 if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
1223 if (cpu == last_cpu + 1) {
1226 if (last_cpu != first_cpu)
1227 printf("-0x%lx", last_cpu);
1228 last_cpu = first_cpu = cpu;
1229 printf(" 0x%lx", cpu);
1233 if (last_cpu != first_cpu)
1234 printf("-0x%lx", last_cpu);
1238 /* try to switch to cpu specified */
1239 if (!cpumask_test_cpu(cpu, &cpus_in_xmon)) {
1240 printf("cpu 0x%lx isn't in xmon\n", cpu);
1242 printf("backtrace of paca[0x%lx].saved_r1 (possibly stale):\n", cpu);
1243 xmon_show_stack(paca_ptrs[cpu]->saved_r1, 0, 0);
1251 while (!xmon_taken) {
1252 if (--timeout == 0) {
1253 if (test_and_set_bit(0, &xmon_taken))
1255 /* take control back */
1257 xmon_owner = smp_processor_id();
1258 printf("cpu 0x%lx didn't take control\n", cpu);
1266 #endif /* CONFIG_SMP */
1269 static unsigned short fcstab[256] = {
1270 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
1271 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
1272 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
1273 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1274 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1275 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1276 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1277 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1278 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1279 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1280 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1281 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1282 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1283 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1284 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1285 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1286 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1287 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1288 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1289 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1290 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1291 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1292 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1293 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1294 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1295 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1296 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1297 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1298 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1299 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1300 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1301 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1304 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1313 if (!scanhex(&adrs))
1315 if (!scanhex(&ncsum))
1318 for (i = 0; i < ncsum; ++i) {
1319 if (mread(adrs+i, &v, 1) == 0) {
1320 printf("csum stopped at "REG"\n", adrs+i);
1325 printf("%x\n", fcs);
1329 * Check if this is a suitable place to put a breakpoint.
1331 static long check_bp_loc(unsigned long addr)
1336 if (!is_kernel_addr(addr)) {
1337 printf("Breakpoints may only be placed at kernel addresses\n");
1340 if (!mread(addr, &instr, sizeof(instr))) {
1341 printf("Can't read instruction at address %lx\n", addr);
1344 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1345 printf("Breakpoints may not be placed on mtmsrd or rfid "
1352 static char *breakpoint_help_string =
1353 "Breakpoint command usage:\n"
1354 "b show breakpoints\n"
1355 "b <addr> [cnt] set breakpoint at given instr addr\n"
1356 "bc clear all breakpoints\n"
1357 "bc <n/addr> clear breakpoint number n or at addr\n"
1358 "bi <addr> [cnt] set hardware instr breakpoint (POWER8 only)\n"
1359 "bd <addr> [cnt] set hardware data breakpoint\n"
1373 #ifndef CONFIG_PPC_8xx
1374 static const char badaddr[] = "Only kernel addresses are permitted for breakpoints\n";
1376 case 'd': /* bd - hardware data breakpoint */
1378 printf(xmon_ro_msg);
1381 if (!ppc_breakpoint_available()) {
1382 printf("Hardware data breakpoint not supported on this cpu\n");
1389 else if (cmd == 'w')
1395 if (scanhex(&dabr.address)) {
1396 if (!is_kernel_addr(dabr.address)) {
1400 dabr.address &= ~HW_BRK_TYPE_DABR;
1401 dabr.enabled = mode | BP_DABR;
1404 force_enable_xmon();
1407 case 'i': /* bi - hardware instr breakpoint */
1409 printf(xmon_ro_msg);
1412 if (!cpu_has_feature(CPU_FTR_ARCH_207S)) {
1413 printf("Hardware instruction breakpoint "
1414 "not supported on this cpu\n");
1418 iabr->enabled &= ~BP_CIABR;
1423 if (!check_bp_loc(a))
1425 bp = new_breakpoint(a);
1427 bp->enabled |= BP_CIABR;
1429 force_enable_xmon();
1436 /* clear all breakpoints */
1437 for (i = 0; i < NBPTS; ++i)
1438 bpts[i].enabled = 0;
1441 printf("All breakpoints cleared\n");
1445 if (a <= NBPTS && a >= 1) {
1446 /* assume a breakpoint number */
1447 bp = &bpts[a-1]; /* bp nums are 1 based */
1449 /* assume a breakpoint address */
1450 bp = at_breakpoint(a);
1452 printf("No breakpoint at %lx\n", a);
1457 printf("Cleared breakpoint %tx (", BP_NUM(bp));
1458 xmon_print_symbol(bp->address, " ", ")\n");
1466 printf(breakpoint_help_string);
1471 if (xmon_is_ro || !scanhex(&a)) {
1472 /* print all breakpoints */
1473 printf(" type address\n");
1475 printf(" data "REG" [", dabr.address);
1476 if (dabr.enabled & 1)
1478 if (dabr.enabled & 2)
1482 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1485 printf("%tx %s ", BP_NUM(bp),
1486 (bp->enabled & BP_CIABR) ? "inst": "trap");
1487 xmon_print_symbol(bp->address, " ", "\n");
1492 if (!check_bp_loc(a))
1494 bp = new_breakpoint(a);
1496 bp->enabled |= BP_TRAP;
1497 force_enable_xmon();
1503 /* Very cheap human name for vector lookup. */
1505 const char *getvecname(unsigned long vec)
1510 case 0x100: ret = "(System Reset)"; break;
1511 case 0x200: ret = "(Machine Check)"; break;
1512 case 0x300: ret = "(Data Access)"; break;
1514 if (radix_enabled())
1515 ret = "(Data Access Out of Range)";
1517 ret = "(Data SLB Access)";
1519 case 0x400: ret = "(Instruction Access)"; break;
1521 if (radix_enabled())
1522 ret = "(Instruction Access Out of Range)";
1524 ret = "(Instruction SLB Access)";
1526 case 0x500: ret = "(Hardware Interrupt)"; break;
1527 case 0x600: ret = "(Alignment)"; break;
1528 case 0x700: ret = "(Program Check)"; break;
1529 case 0x800: ret = "(FPU Unavailable)"; break;
1530 case 0x900: ret = "(Decrementer)"; break;
1531 case 0x980: ret = "(Hypervisor Decrementer)"; break;
1532 case 0xa00: ret = "(Doorbell)"; break;
1533 case 0xc00: ret = "(System Call)"; break;
1534 case 0xd00: ret = "(Single Step)"; break;
1535 case 0xe40: ret = "(Emulation Assist)"; break;
1536 case 0xe60: ret = "(HMI)"; break;
1537 case 0xe80: ret = "(Hypervisor Doorbell)"; break;
1538 case 0xf00: ret = "(Performance Monitor)"; break;
1539 case 0xf20: ret = "(Altivec Unavailable)"; break;
1540 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1541 case 0x1500: ret = "(Denormalisation)"; break;
1542 case 0x1700: ret = "(Altivec Assist)"; break;
1548 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1549 unsigned long *endp)
1551 unsigned long size, offset;
1554 *startp = *endp = 0;
1557 if (setjmp(bus_error_jmp) == 0) {
1558 catch_memory_errors = 1;
1560 name = kallsyms_lookup(pc, &size, &offset, NULL, tmpstr);
1562 *startp = pc - offset;
1563 *endp = pc - offset + size;
1567 catch_memory_errors = 0;
1570 #define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1571 #define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long))
1573 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1576 int max_to_print = 64;
1578 unsigned long newsp;
1579 unsigned long marker;
1580 struct pt_regs regs;
1582 while (max_to_print--) {
1583 if (!is_kernel_addr(sp)) {
1585 printf("SP (%lx) is in userspace\n", sp);
1589 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1590 || !mread(sp, &newsp, sizeof(unsigned long))) {
1591 printf("Couldn't read stack frame at %lx\n", sp);
1596 * For the first stack frame, try to work out if
1597 * LR and/or the saved LR value in the bottommost
1598 * stack frame are valid.
1600 if ((pc | lr) != 0) {
1601 unsigned long fnstart, fnend;
1602 unsigned long nextip;
1605 get_function_bounds(pc, &fnstart, &fnend);
1608 mread(newsp + LRSAVE_OFFSET, &nextip,
1609 sizeof(unsigned long));
1611 if (!is_kernel_addr(lr)
1612 || (fnstart <= lr && lr < fnend))
1614 } else if (lr == nextip) {
1616 } else if (is_kernel_addr(lr)
1617 && !(fnstart <= lr && lr < fnend)) {
1618 printf("[link register ] ");
1619 xmon_print_symbol(lr, " ", "\n");
1622 printf("["REG"] ", sp);
1623 xmon_print_symbol(ip, " ", " (unreliable)\n");
1628 printf("["REG"] ", sp);
1629 xmon_print_symbol(ip, " ", "\n");
1632 /* Look for "regshere" marker to see if this is
1633 an exception frame. */
1634 if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1635 && marker == STACK_FRAME_REGS_MARKER) {
1636 if (mread(sp + STACK_FRAME_OVERHEAD, ®s, sizeof(regs))
1638 printf("Couldn't read registers at %lx\n",
1639 sp + STACK_FRAME_OVERHEAD);
1642 printf("--- Exception: %lx %s at ", regs.trap,
1643 getvecname(TRAP(®s)));
1646 xmon_print_symbol(pc, " ", "\n");
1656 static void backtrace(struct pt_regs *excp)
1661 xmon_show_stack(sp, 0, 0);
1663 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1667 static void print_bug_trap(struct pt_regs *regs)
1670 const struct bug_entry *bug;
1673 if (regs->msr & MSR_PR)
1674 return; /* not in kernel */
1675 addr = regs->nip; /* address of trap instruction */
1676 if (!is_kernel_addr(addr))
1678 bug = find_bug(regs->nip);
1681 if (is_warning_bug(bug))
1684 #ifdef CONFIG_DEBUG_BUGVERBOSE
1685 printf("kernel BUG at %s:%u!\n",
1686 bug->file, bug->line);
1688 printf("kernel BUG at %px!\n", (void *)bug->bug_addr);
1690 #endif /* CONFIG_BUG */
1693 static void excprint(struct pt_regs *fp)
1698 printf("cpu 0x%x: ", smp_processor_id());
1699 #endif /* CONFIG_SMP */
1702 printf("Vector: %lx %s at [%px]\n", fp->trap, getvecname(trap), fp);
1704 xmon_print_symbol(fp->nip, ": ", "\n");
1707 xmon_print_symbol(fp->link, ": ", "\n");
1709 printf(" sp: %lx\n", fp->gpr[1]);
1710 printf(" msr: %lx\n", fp->msr);
1712 if (trap == 0x300 || trap == 0x380 || trap == 0x600 || trap == 0x200) {
1713 printf(" dar: %lx\n", fp->dar);
1715 printf(" dsisr: %lx\n", fp->dsisr);
1718 printf(" current = 0x%px\n", current);
1720 printf(" paca = 0x%px\t irqmask: 0x%02x\t irq_happened: 0x%02x\n",
1721 local_paca, local_paca->irq_soft_mask, local_paca->irq_happened);
1724 printf(" pid = %d, comm = %s\n",
1725 current->pid, current->comm);
1731 printf(linux_banner);
1734 static void prregs(struct pt_regs *fp)
1738 struct pt_regs regs;
1740 if (scanhex(&base)) {
1741 if (setjmp(bus_error_jmp) == 0) {
1742 catch_memory_errors = 1;
1744 regs = *(struct pt_regs *)base;
1748 catch_memory_errors = 0;
1749 printf("*** Error reading registers from "REG"\n",
1753 catch_memory_errors = 0;
1758 if (FULL_REGS(fp)) {
1759 for (n = 0; n < 16; ++n)
1760 printf("R%.2d = "REG" R%.2d = "REG"\n",
1761 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1763 for (n = 0; n < 7; ++n)
1764 printf("R%.2d = "REG" R%.2d = "REG"\n",
1765 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1768 for (n = 0; n < 32; ++n) {
1769 printf("R%.2d = %.8lx%s", n, fp->gpr[n],
1770 (n & 3) == 3? "\n": " ");
1771 if (n == 12 && !FULL_REGS(fp)) {
1778 xmon_print_symbol(fp->nip, " ", "\n");
1779 if (TRAP(fp) != 0xc00 && cpu_has_feature(CPU_FTR_CFAR)) {
1781 xmon_print_symbol(fp->orig_gpr3, " ", "\n");
1784 xmon_print_symbol(fp->link, " ", "\n");
1785 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
1786 printf("ctr = "REG" xer = "REG" trap = %4lx\n",
1787 fp->ctr, fp->xer, fp->trap);
1789 if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1790 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1793 static void cacheflush(void)
1796 unsigned long nflush;
1801 scanhex((void *)&adrs);
1806 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1807 if (setjmp(bus_error_jmp) == 0) {
1808 catch_memory_errors = 1;
1812 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1813 cflush((void *) adrs);
1815 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1816 cinval((void *) adrs);
1819 /* wait a little while to see if we get a machine check */
1822 catch_memory_errors = 0;
1825 extern unsigned long xmon_mfspr(int spr, unsigned long default_value);
1826 extern void xmon_mtspr(int spr, unsigned long value);
1829 read_spr(int n, unsigned long *vp)
1831 unsigned long ret = -1UL;
1834 if (setjmp(bus_error_jmp) == 0) {
1835 catch_spr_faults = 1;
1838 ret = xmon_mfspr(n, *vp);
1844 catch_spr_faults = 0;
1850 write_spr(int n, unsigned long val)
1853 printf(xmon_ro_msg);
1857 if (setjmp(bus_error_jmp) == 0) {
1858 catch_spr_faults = 1;
1865 printf("SPR 0x%03x (%4d) Faulted during write\n", n, n);
1867 catch_spr_faults = 0;
1870 static void dump_206_sprs(void)
1873 if (!cpu_has_feature(CPU_FTR_ARCH_206))
1876 /* Actually some of these pre-date 2.06, but whatevs */
1878 printf("srr0 = %.16lx srr1 = %.16lx dsisr = %.8lx\n",
1879 mfspr(SPRN_SRR0), mfspr(SPRN_SRR1), mfspr(SPRN_DSISR));
1880 printf("dscr = %.16lx ppr = %.16lx pir = %.8lx\n",
1881 mfspr(SPRN_DSCR), mfspr(SPRN_PPR), mfspr(SPRN_PIR));
1882 printf("amr = %.16lx uamor = %.16lx\n",
1883 mfspr(SPRN_AMR), mfspr(SPRN_UAMOR));
1885 if (!(mfmsr() & MSR_HV))
1888 printf("sdr1 = %.16lx hdar = %.16lx hdsisr = %.8lx\n",
1889 mfspr(SPRN_SDR1), mfspr(SPRN_HDAR), mfspr(SPRN_HDSISR));
1890 printf("hsrr0 = %.16lx hsrr1 = %.16lx hdec = %.16lx\n",
1891 mfspr(SPRN_HSRR0), mfspr(SPRN_HSRR1), mfspr(SPRN_HDEC));
1892 printf("lpcr = %.16lx pcr = %.16lx lpidr = %.8lx\n",
1893 mfspr(SPRN_LPCR), mfspr(SPRN_PCR), mfspr(SPRN_LPID));
1894 printf("hsprg0 = %.16lx hsprg1 = %.16lx amor = %.16lx\n",
1895 mfspr(SPRN_HSPRG0), mfspr(SPRN_HSPRG1), mfspr(SPRN_AMOR));
1896 printf("dabr = %.16lx dabrx = %.16lx\n",
1897 mfspr(SPRN_DABR), mfspr(SPRN_DABRX));
1901 static void dump_207_sprs(void)
1906 if (!cpu_has_feature(CPU_FTR_ARCH_207S))
1909 printf("dpdes = %.16lx tir = %.16lx cir = %.8lx\n",
1910 mfspr(SPRN_DPDES), mfspr(SPRN_TIR), mfspr(SPRN_CIR));
1912 printf("fscr = %.16lx tar = %.16lx pspb = %.8lx\n",
1913 mfspr(SPRN_FSCR), mfspr(SPRN_TAR), mfspr(SPRN_PSPB));
1917 /* Only if TM has been enabled in the kernel */
1918 printf("tfhar = %.16lx tfiar = %.16lx texasr = %.16lx\n",
1919 mfspr(SPRN_TFHAR), mfspr(SPRN_TFIAR),
1920 mfspr(SPRN_TEXASR));
1923 printf("mmcr0 = %.16lx mmcr1 = %.16lx mmcr2 = %.16lx\n",
1924 mfspr(SPRN_MMCR0), mfspr(SPRN_MMCR1), mfspr(SPRN_MMCR2));
1925 printf("pmc1 = %.8lx pmc2 = %.8lx pmc3 = %.8lx pmc4 = %.8lx\n",
1926 mfspr(SPRN_PMC1), mfspr(SPRN_PMC2),
1927 mfspr(SPRN_PMC3), mfspr(SPRN_PMC4));
1928 printf("mmcra = %.16lx siar = %.16lx pmc5 = %.8lx\n",
1929 mfspr(SPRN_MMCRA), mfspr(SPRN_SIAR), mfspr(SPRN_PMC5));
1930 printf("sdar = %.16lx sier = %.16lx pmc6 = %.8lx\n",
1931 mfspr(SPRN_SDAR), mfspr(SPRN_SIER), mfspr(SPRN_PMC6));
1932 printf("ebbhr = %.16lx ebbrr = %.16lx bescr = %.16lx\n",
1933 mfspr(SPRN_EBBHR), mfspr(SPRN_EBBRR), mfspr(SPRN_BESCR));
1934 printf("iamr = %.16lx\n", mfspr(SPRN_IAMR));
1936 if (!(msr & MSR_HV))
1939 printf("hfscr = %.16lx dhdes = %.16lx rpr = %.16lx\n",
1940 mfspr(SPRN_HFSCR), mfspr(SPRN_DHDES), mfspr(SPRN_RPR));
1941 printf("dawr = %.16lx dawrx = %.16lx ciabr = %.16lx\n",
1942 mfspr(SPRN_DAWR), mfspr(SPRN_DAWRX), mfspr(SPRN_CIABR));
1946 static void dump_300_sprs(void)
1949 bool hv = mfmsr() & MSR_HV;
1951 if (!cpu_has_feature(CPU_FTR_ARCH_300))
1954 printf("pidr = %.16lx tidr = %.16lx\n",
1955 mfspr(SPRN_PID), mfspr(SPRN_TIDR));
1956 printf("psscr = %.16lx\n",
1957 hv ? mfspr(SPRN_PSSCR) : mfspr(SPRN_PSSCR_PR));
1962 printf("ptcr = %.16lx asdr = %.16lx\n",
1963 mfspr(SPRN_PTCR), mfspr(SPRN_ASDR));
1967 static void dump_one_spr(int spr, bool show_unimplemented)
1972 if (!read_spr(spr, &val)) {
1973 printf("SPR 0x%03x (%4d) Faulted during read\n", spr, spr);
1977 if (val == 0xdeadbeef) {
1978 /* Looks like read was a nop, confirm */
1980 if (!read_spr(spr, &val)) {
1981 printf("SPR 0x%03x (%4d) Faulted during read\n", spr, spr);
1985 if (val == 0x0badcafe) {
1986 if (show_unimplemented)
1987 printf("SPR 0x%03x (%4d) Unimplemented\n", spr, spr);
1992 printf("SPR 0x%03x (%4d) = 0x%lx\n", spr, spr, val);
1995 static void super_regs(void)
1997 static unsigned long regno;
2005 unsigned long sp, toc;
2006 asm("mr %0,1" : "=r" (sp) :);
2007 asm("mr %0,2" : "=r" (toc) :);
2009 printf("msr = "REG" sprg0 = "REG"\n",
2010 mfmsr(), mfspr(SPRN_SPRG0));
2011 printf("pvr = "REG" sprg1 = "REG"\n",
2012 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
2013 printf("dec = "REG" sprg2 = "REG"\n",
2014 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
2015 printf("sp = "REG" sprg3 = "REG"\n", sp, mfspr(SPRN_SPRG3));
2016 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
2028 read_spr(regno, &val);
2030 write_spr(regno, val);
2031 dump_one_spr(regno, true);
2036 dump_one_spr(regno, true);
2040 for (spr = 1; spr < 1024; ++spr)
2041 dump_one_spr(spr, false);
2049 * Stuff for reading and writing memory safely
2052 mread(unsigned long adrs, void *buf, int size)
2058 if (setjmp(bus_error_jmp) == 0) {
2059 catch_memory_errors = 1;
2065 *(u16 *)q = *(u16 *)p;
2068 *(u32 *)q = *(u32 *)p;
2071 *(u64 *)q = *(u64 *)p;
2074 for( ; n < size; ++n) {
2080 /* wait a little while to see if we get a machine check */
2084 catch_memory_errors = 0;
2089 mwrite(unsigned long adrs, void *buf, int size)
2097 printf(xmon_ro_msg);
2101 if (setjmp(bus_error_jmp) == 0) {
2102 catch_memory_errors = 1;
2108 *(u16 *)p = *(u16 *)q;
2111 *(u32 *)p = *(u32 *)q;
2114 *(u64 *)p = *(u64 *)q;
2117 for ( ; n < size; ++n) {
2123 /* wait a little while to see if we get a machine check */
2127 printf("*** Error writing address "REG"\n", adrs + n);
2129 catch_memory_errors = 0;
2133 static int fault_type;
2134 static int fault_except;
2135 static char *fault_chars[] = { "--", "**", "##" };
2137 static int handle_fault(struct pt_regs *regs)
2139 fault_except = TRAP(regs);
2140 switch (TRAP(regs)) {
2152 longjmp(bus_error_jmp, 1);
2157 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
2160 byterev(unsigned char *val, int size)
2166 SWAP(val[0], val[1], t);
2169 SWAP(val[0], val[3], t);
2170 SWAP(val[1], val[2], t);
2172 case 8: /* is there really any use for this? */
2173 SWAP(val[0], val[7], t);
2174 SWAP(val[1], val[6], t);
2175 SWAP(val[2], val[5], t);
2176 SWAP(val[3], val[4], t);
2184 static char *memex_help_string =
2185 "Memory examine command usage:\n"
2186 "m [addr] [flags] examine/change memory\n"
2187 " addr is optional. will start where left off.\n"
2188 " flags may include chars from this set:\n"
2189 " b modify by bytes (default)\n"
2190 " w modify by words (2 byte)\n"
2191 " l modify by longs (4 byte)\n"
2192 " d modify by doubleword (8 byte)\n"
2193 " r toggle reverse byte order mode\n"
2194 " n do not read memory (for i/o spaces)\n"
2195 " . ok to read (default)\n"
2196 "NOTE: flags are saved as defaults\n"
2199 static char *memex_subcmd_help_string =
2200 "Memory examine subcommands:\n"
2201 " hexval write this val to current location\n"
2202 " 'string' write chars from string to this location\n"
2203 " ' increment address\n"
2204 " ^ decrement address\n"
2205 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
2206 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
2207 " ` clear no-read flag\n"
2208 " ; stay at this addr\n"
2209 " v change to byte mode\n"
2210 " w change to word (2 byte) mode\n"
2211 " l change to long (4 byte) mode\n"
2212 " u change to doubleword (8 byte) mode\n"
2213 " m addr change current addr\n"
2214 " n toggle no-read flag\n"
2215 " r toggle byte reverse flag\n"
2216 " < count back up count bytes\n"
2217 " > count skip forward count bytes\n"
2218 " x exit this mode\n"
2224 int cmd, inc, i, nslash;
2226 unsigned char val[16];
2228 scanhex((void *)&adrs);
2231 printf(memex_help_string);
2237 while ((cmd = skipbl()) != '\n') {
2239 case 'b': size = 1; break;
2240 case 'w': size = 2; break;
2241 case 'l': size = 4; break;
2242 case 'd': size = 8; break;
2243 case 'r': brev = !brev; break;
2244 case 'n': mnoread = 1; break;
2245 case '.': mnoread = 0; break;
2254 n = mread(adrs, val, size);
2255 printf(REG"%c", adrs, brev? 'r': ' ');
2260 for (i = 0; i < n; ++i)
2261 printf("%.2x", val[i]);
2262 for (; i < size; ++i)
2263 printf("%s", fault_chars[fault_type]);
2270 for (i = 0; i < size; ++i)
2271 val[i] = n >> (i * 8);
2274 mwrite(adrs, val, size);
2287 else if( n == '\'' )
2289 for (i = 0; i < size; ++i)
2290 val[i] = n >> (i * 8);
2293 mwrite(adrs, val, size);
2329 adrs -= 1 << nslash;
2333 adrs += 1 << nslash;
2337 adrs += 1 << -nslash;
2341 adrs -= 1 << -nslash;
2344 scanhex((void *)&adrs);
2363 printf(memex_subcmd_help_string);
2378 case 'n': c = '\n'; break;
2379 case 'r': c = '\r'; break;
2380 case 'b': c = '\b'; break;
2381 case 't': c = '\t'; break;
2386 static void xmon_rawdump (unsigned long adrs, long ndump)
2389 unsigned char temp[16];
2391 for (n = ndump; n > 0;) {
2393 nr = mread(adrs, temp, r);
2395 for (m = 0; m < r; ++m) {
2397 printf("%.2x", temp[m]);
2399 printf("%s", fault_chars[fault_type]);
2408 static void dump_tracing(void)
2414 ftrace_dump(DUMP_ORIG);
2416 ftrace_dump(DUMP_ALL);
2420 static void dump_one_paca(int cpu)
2422 struct paca_struct *p;
2423 #ifdef CONFIG_PPC_BOOK3S_64
2427 if (setjmp(bus_error_jmp) != 0) {
2428 printf("*** Error dumping paca for cpu 0x%x!\n", cpu);
2432 catch_memory_errors = 1;
2437 printf("paca for cpu 0x%x @ %px:\n", cpu, p);
2439 printf(" %-*s = %s\n", 25, "possible", cpu_possible(cpu) ? "yes" : "no");
2440 printf(" %-*s = %s\n", 25, "present", cpu_present(cpu) ? "yes" : "no");
2441 printf(" %-*s = %s\n", 25, "online", cpu_online(cpu) ? "yes" : "no");
2443 #define DUMP(paca, name, format) \
2444 printf(" %-*s = "format"\t(0x%lx)\n", 25, #name, 18, paca->name, \
2445 offsetof(struct paca_struct, name));
2447 DUMP(p, lock_token, "%#-*x");
2448 DUMP(p, paca_index, "%#-*x");
2449 DUMP(p, kernel_toc, "%#-*llx");
2450 DUMP(p, kernelbase, "%#-*llx");
2451 DUMP(p, kernel_msr, "%#-*llx");
2452 DUMP(p, emergency_sp, "%-*px");
2453 #ifdef CONFIG_PPC_BOOK3S_64
2454 DUMP(p, nmi_emergency_sp, "%-*px");
2455 DUMP(p, mc_emergency_sp, "%-*px");
2456 DUMP(p, in_nmi, "%#-*x");
2457 DUMP(p, in_mce, "%#-*x");
2458 DUMP(p, hmi_event_available, "%#-*x");
2460 DUMP(p, data_offset, "%#-*llx");
2461 DUMP(p, hw_cpu_id, "%#-*x");
2462 DUMP(p, cpu_start, "%#-*x");
2463 DUMP(p, kexec_state, "%#-*x");
2464 #ifdef CONFIG_PPC_BOOK3S_64
2465 if (!early_radix_enabled()) {
2466 for (i = 0; i < SLB_NUM_BOLTED; i++) {
2469 if (!p->slb_shadow_ptr)
2472 esid = be64_to_cpu(p->slb_shadow_ptr->save_area[i].esid);
2473 vsid = be64_to_cpu(p->slb_shadow_ptr->save_area[i].vsid);
2476 printf(" %-*s[%d] = 0x%016llx 0x%016llx\n",
2477 22, "slb_shadow", i, esid, vsid);
2480 DUMP(p, vmalloc_sllp, "%#-*x");
2481 DUMP(p, stab_rr, "%#-*x");
2482 DUMP(p, slb_used_bitmap, "%#-*x");
2483 DUMP(p, slb_kern_bitmap, "%#-*x");
2485 if (!early_cpu_has_feature(CPU_FTR_ARCH_300)) {
2486 DUMP(p, slb_cache_ptr, "%#-*x");
2487 for (i = 0; i < SLB_CACHE_ENTRIES; i++)
2488 printf(" %-*s[%d] = 0x%016x\n",
2489 22, "slb_cache", i, p->slb_cache[i]);
2493 DUMP(p, rfi_flush_fallback_area, "%-*px");
2495 DUMP(p, dscr_default, "%#-*llx");
2496 #ifdef CONFIG_PPC_BOOK3E
2497 DUMP(p, pgd, "%-*px");
2498 DUMP(p, kernel_pgd, "%-*px");
2499 DUMP(p, tcd_ptr, "%-*px");
2500 DUMP(p, mc_kstack, "%-*px");
2501 DUMP(p, crit_kstack, "%-*px");
2502 DUMP(p, dbg_kstack, "%-*px");
2504 DUMP(p, __current, "%-*px");
2505 DUMP(p, kstack, "%#-*llx");
2506 printf(" %-*s = 0x%016llx\n", 25, "kstack_base", p->kstack & ~(THREAD_SIZE - 1));
2507 #ifdef CONFIG_STACKPROTECTOR
2508 DUMP(p, canary, "%#-*lx");
2510 DUMP(p, saved_r1, "%#-*llx");
2511 #ifdef CONFIG_PPC_BOOK3E
2512 DUMP(p, trap_save, "%#-*x");
2514 DUMP(p, irq_soft_mask, "%#-*x");
2515 DUMP(p, irq_happened, "%#-*x");
2516 #ifdef CONFIG_MMIOWB
2517 DUMP(p, mmiowb_state.nesting_count, "%#-*x");
2518 DUMP(p, mmiowb_state.mmiowb_pending, "%#-*x");
2520 DUMP(p, irq_work_pending, "%#-*x");
2521 DUMP(p, sprg_vdso, "%#-*llx");
2523 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
2524 DUMP(p, tm_scratch, "%#-*llx");
2527 #ifdef CONFIG_PPC_POWERNV
2528 DUMP(p, idle_state, "%#-*lx");
2529 if (!early_cpu_has_feature(CPU_FTR_ARCH_300)) {
2530 DUMP(p, thread_idle_state, "%#-*x");
2531 DUMP(p, subcore_sibling_mask, "%#-*x");
2533 #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
2534 DUMP(p, requested_psscr, "%#-*llx");
2535 DUMP(p, dont_stop.counter, "%#-*x");
2540 DUMP(p, accounting.utime, "%#-*lx");
2541 DUMP(p, accounting.stime, "%#-*lx");
2542 #ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
2543 DUMP(p, accounting.utime_scaled, "%#-*lx");
2545 DUMP(p, accounting.starttime, "%#-*lx");
2546 DUMP(p, accounting.starttime_user, "%#-*lx");
2547 #ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
2548 DUMP(p, accounting.startspurr, "%#-*lx");
2549 DUMP(p, accounting.utime_sspurr, "%#-*lx");
2551 DUMP(p, accounting.steal_time, "%#-*lx");
2554 catch_memory_errors = 0;
2558 static void dump_all_pacas(void)
2562 if (num_possible_cpus() == 0) {
2563 printf("No possible cpus, use 'dp #' to dump individual cpus\n");
2567 for_each_possible_cpu(cpu)
2571 static void dump_pacas(void)
2582 termch = c; /* Put c back, it wasn't 'a' */
2587 dump_one_paca(xmon_owner);
2591 #ifdef CONFIG_PPC_POWERNV
2592 static void dump_one_xive(int cpu)
2594 unsigned int hwid = get_hard_smp_processor_id(cpu);
2595 bool hv = cpu_has_feature(CPU_FTR_HVMODE);
2598 opal_xive_dump(XIVE_DUMP_TM_HYP, hwid);
2599 opal_xive_dump(XIVE_DUMP_TM_POOL, hwid);
2600 opal_xive_dump(XIVE_DUMP_TM_OS, hwid);
2601 opal_xive_dump(XIVE_DUMP_TM_USER, hwid);
2602 opal_xive_dump(XIVE_DUMP_VP, hwid);
2603 opal_xive_dump(XIVE_DUMP_EMU_STATE, hwid);
2606 if (setjmp(bus_error_jmp) != 0) {
2607 catch_memory_errors = 0;
2608 printf("*** Error dumping xive on cpu %d\n", cpu);
2612 catch_memory_errors = 1;
2614 xmon_xive_do_dump(cpu);
2617 catch_memory_errors = 0;
2620 static void dump_all_xives(void)
2624 if (num_possible_cpus() == 0) {
2625 printf("No possible cpus, use 'dx #' to dump individual cpus\n");
2629 for_each_possible_cpu(cpu)
2633 static void dump_one_xive_irq(u32 num, struct irq_data *d)
2635 xmon_xive_get_irq_config(num, d);
2638 static void dump_all_xive_irq(void)
2641 struct irq_desc *desc;
2643 for_each_irq_desc(i, desc) {
2644 struct irq_data *d = irq_desc_get_irq_data(desc);
2650 hwirq = (unsigned int)irqd_to_hwirq(d);
2651 /* IPIs are special (HW number 0) */
2653 dump_one_xive_irq(hwirq, d);
2657 static void dump_xives(void)
2662 if (!xive_enabled()) {
2663 printf("Xive disabled on this system\n");
2671 } else if (c == 'i') {
2673 dump_one_xive_irq(num, NULL);
2675 dump_all_xive_irq();
2679 termch = c; /* Put c back, it wasn't 'a' */
2684 dump_one_xive(xmon_owner);
2686 #endif /* CONFIG_PPC_POWERNV */
2688 static void dump_by_size(unsigned long addr, long count, int size)
2690 unsigned char temp[16];
2694 count = ALIGN(count, 16);
2696 for (i = 0; i < count; i += 16, addr += 16) {
2699 if (mread(addr, temp, 16) != 16) {
2700 printf("\nFaulted reading %d bytes from 0x"REG"\n", 16, addr);
2704 for (j = 0; j < 16; j += size) {
2707 case 1: val = temp[j]; break;
2708 case 2: val = *(u16 *)&temp[j]; break;
2709 case 4: val = *(u32 *)&temp[j]; break;
2710 case 8: val = *(u64 *)&temp[j]; break;
2714 printf("%0*llx", size * 2, val);
2717 for (j = 0; j < 16; ++j) {
2719 putchar(' ' <= val && val <= '~' ? val : '.');
2728 static char last[] = { "d?\n" };
2735 xmon_start_pagination();
2737 xmon_end_pagination();
2741 #ifdef CONFIG_PPC_POWERNV
2743 xmon_start_pagination();
2745 xmon_end_pagination();
2758 scanhex((void *)&adrs);
2765 else if (nidump > MAX_IDUMP)
2767 adrs += ppc_inst_dump(adrs, nidump, 1);
2769 } else if (c == 'l') {
2771 } else if (c == 'o') {
2773 } else if (c == 'v') {
2774 /* dump virtual to physical translation */
2776 } else if (c == 'r') {
2780 xmon_rawdump(adrs, ndump);
2787 else if (ndump > MAX_DUMP)
2795 ndump = ALIGN(ndump, 16);
2796 dump_by_size(adrs, ndump, c - '0');
2801 prdump(adrs, ndump);
2810 prdump(unsigned long adrs, long ndump)
2812 long n, m, c, r, nr;
2813 unsigned char temp[16];
2815 for (n = ndump; n > 0;) {
2819 nr = mread(adrs, temp, r);
2821 for (m = 0; m < r; ++m) {
2822 if ((m & (sizeof(long) - 1)) == 0 && m > 0)
2825 printf("%.2x", temp[m]);
2827 printf("%s", fault_chars[fault_type]);
2829 for (; m < 16; ++m) {
2830 if ((m & (sizeof(long) - 1)) == 0)
2835 for (m = 0; m < r; ++m) {
2838 putchar(' ' <= c && c <= '~'? c: '.');
2851 typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr);
2854 generic_inst_dump(unsigned long adr, long count, int praddr,
2855 instruction_dump_func dump_func)
2858 unsigned long first_adr;
2859 unsigned int inst, last_inst = 0;
2860 unsigned char val[4];
2863 for (first_adr = adr; count > 0; --count, adr += 4) {
2864 nr = mread(adr, val, 4);
2867 const char *x = fault_chars[fault_type];
2868 printf(REG" %s%s%s%s\n", adr, x, x, x, x);
2872 inst = GETWORD(val);
2873 if (adr > first_adr && inst == last_inst) {
2883 printf(REG" %.8x", adr, inst);
2885 dump_func(inst, adr);
2888 return adr - first_adr;
2892 ppc_inst_dump(unsigned long adr, long count, int praddr)
2894 return generic_inst_dump(adr, count, praddr, print_insn_powerpc);
2898 print_address(unsigned long addr)
2900 xmon_print_symbol(addr, "\t# ", "");
2906 struct kmsg_dumper dumper = { .active = 1 };
2907 unsigned char buf[128];
2910 if (setjmp(bus_error_jmp) != 0) {
2911 printf("Error dumping printk buffer!\n");
2915 catch_memory_errors = 1;
2918 kmsg_dump_rewind_nolock(&dumper);
2919 xmon_start_pagination();
2920 while (kmsg_dump_get_line_nolock(&dumper, false, buf, sizeof(buf), &len)) {
2924 xmon_end_pagination();
2927 /* wait a little while to see if we get a machine check */
2929 catch_memory_errors = 0;
2932 #ifdef CONFIG_PPC_POWERNV
2933 static void dump_opal_msglog(void)
2935 unsigned char buf[128];
2939 if (!firmware_has_feature(FW_FEATURE_OPAL)) {
2940 printf("Machine is not running OPAL firmware.\n");
2944 if (setjmp(bus_error_jmp) != 0) {
2945 printf("Error dumping OPAL msglog!\n");
2949 catch_memory_errors = 1;
2952 xmon_start_pagination();
2953 while ((res = opal_msglog_copy(buf, pos, sizeof(buf) - 1))) {
2955 printf("Error dumping OPAL msglog! Error: %zd\n", res);
2962 xmon_end_pagination();
2965 /* wait a little while to see if we get a machine check */
2967 catch_memory_errors = 0;
2972 * Memory operations - move, set, print differences
2974 static unsigned long mdest; /* destination address */
2975 static unsigned long msrc; /* source address */
2976 static unsigned long mval; /* byte value to set memory to */
2977 static unsigned long mcount; /* # bytes to affect */
2978 static unsigned long mdiffs; /* max # differences to print */
2983 scanhex((void *)&mdest);
2984 if( termch != '\n' )
2986 scanhex((void *)(cmd == 's'? &mval: &msrc));
2987 if( termch != '\n' )
2989 scanhex((void *)&mcount);
2993 printf(xmon_ro_msg);
2996 memmove((void *)mdest, (void *)msrc, mcount);
3000 printf(xmon_ro_msg);
3003 memset((void *)mdest, mval, mcount);
3006 if( termch != '\n' )
3008 scanhex((void *)&mdiffs);
3009 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
3015 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
3020 for( n = nb; n > 0; --n )
3021 if( *p1++ != *p2++ )
3022 if( ++prt <= maxpr )
3023 printf("%px %.2x # %px %.2x\n", p1 - 1,
3024 p1[-1], p2 - 1, p2[-1]);
3026 printf("Total of %d differences\n", prt);
3029 static unsigned mend;
3030 static unsigned mask;
3036 unsigned char val[4];
3039 scanhex((void *)&mdest);
3040 if (termch != '\n') {
3042 scanhex((void *)&mend);
3043 if (termch != '\n') {
3045 scanhex((void *)&mval);
3047 if (termch != '\n') termch = 0;
3048 scanhex((void *)&mask);
3052 for (a = mdest; a < mend; a += 4) {
3053 if (mread(a, val, 4) == 4
3054 && ((GETWORD(val) ^ mval) & mask) == 0) {
3055 printf("%.16x: %.16x\n", a, GETWORD(val));
3062 static unsigned long mskip = 0x1000;
3063 static unsigned long mlim = 0xffffffff;
3073 if (termch != '\n') termch = 0;
3075 if (termch != '\n') termch = 0;
3078 for (a = mdest; a < mlim; a += mskip) {
3079 ok = mread(a, &v, 1);
3081 printf("%.8x .. ", a);
3082 } else if (!ok && ook)
3083 printf("%.8lx\n", a - mskip);
3089 printf("%.8lx\n", a - mskip);
3092 static void show_task(struct task_struct *tsk)
3097 * Cloned from kdb_task_state_char(), which is not entirely
3098 * appropriate for calling from xmon. This could be moved
3099 * to a common, generic, routine used by both.
3101 state = (tsk->state == 0) ? 'R' :
3102 (tsk->state < 0) ? 'U' :
3103 (tsk->state & TASK_UNINTERRUPTIBLE) ? 'D' :
3104 (tsk->state & TASK_STOPPED) ? 'T' :
3105 (tsk->state & TASK_TRACED) ? 'C' :
3106 (tsk->exit_state & EXIT_ZOMBIE) ? 'Z' :
3107 (tsk->exit_state & EXIT_DEAD) ? 'E' :
3108 (tsk->state & TASK_INTERRUPTIBLE) ? 'S' : '?';
3110 printf("%px %016lx %6d %6d %c %2d %s\n", tsk,
3112 tsk->pid, rcu_dereference(tsk->parent)->pid,
3113 state, task_cpu(tsk),
3117 #ifdef CONFIG_PPC_BOOK3S_64
3118 static void format_pte(void *ptep, unsigned long pte)
3120 pte_t entry = __pte(pte);
3122 printf("ptep @ 0x%016lx = 0x%016lx\n", (unsigned long)ptep, pte);
3123 printf("Maps physical address = 0x%016lx\n", pte & PTE_RPN_MASK);
3125 printf("Flags = %s%s%s%s%s\n",
3126 pte_young(entry) ? "Accessed " : "",
3127 pte_dirty(entry) ? "Dirty " : "",
3128 pte_read(entry) ? "Read " : "",
3129 pte_write(entry) ? "Write " : "",
3130 pte_exec(entry) ? "Exec " : "");
3133 static void show_pte(unsigned long addr)
3135 unsigned long tskv = 0;
3136 struct task_struct *tsk = NULL;
3137 struct mm_struct *mm;
3138 pgd_t *pgdp, *pgdir;
3143 if (!scanhex(&tskv))
3146 tsk = (struct task_struct *)tskv;
3151 mm = tsk->active_mm;
3153 if (setjmp(bus_error_jmp) != 0) {
3154 catch_memory_errors = 0;
3155 printf("*** Error dumping pte for task %px\n", tsk);
3159 catch_memory_errors = 1;
3162 if (mm == &init_mm) {
3163 pgdp = pgd_offset_k(addr);
3164 pgdir = pgd_offset_k(0);
3166 pgdp = pgd_offset(mm, addr);
3167 pgdir = pgd_offset(mm, 0);
3170 if (pgd_none(*pgdp)) {
3171 printf("no linux page table for address\n");
3175 printf("pgd @ 0x%px\n", pgdir);
3177 if (pgd_is_leaf(*pgdp)) {
3178 format_pte(pgdp, pgd_val(*pgdp));
3181 printf("pgdp @ 0x%px = 0x%016lx\n", pgdp, pgd_val(*pgdp));
3183 pudp = pud_offset(pgdp, addr);
3185 if (pud_none(*pudp)) {
3186 printf("No valid PUD\n");
3190 if (pud_is_leaf(*pudp)) {
3191 format_pte(pudp, pud_val(*pudp));
3195 printf("pudp @ 0x%px = 0x%016lx\n", pudp, pud_val(*pudp));
3197 pmdp = pmd_offset(pudp, addr);
3199 if (pmd_none(*pmdp)) {
3200 printf("No valid PMD\n");
3204 if (pmd_is_leaf(*pmdp)) {
3205 format_pte(pmdp, pmd_val(*pmdp));
3208 printf("pmdp @ 0x%px = 0x%016lx\n", pmdp, pmd_val(*pmdp));
3210 ptep = pte_offset_map(pmdp, addr);
3211 if (pte_none(*ptep)) {
3212 printf("no valid PTE\n");
3216 format_pte(ptep, pte_val(*ptep));
3220 catch_memory_errors = 0;
3223 static void show_pte(unsigned long addr)
3225 printf("show_pte not yet implemented\n");
3227 #endif /* CONFIG_PPC_BOOK3S_64 */
3229 static void show_tasks(void)
3232 struct task_struct *tsk = NULL;
3234 printf(" task_struct ->thread.ksp PID PPID S P CMD\n");
3237 tsk = (struct task_struct *)tskv;
3239 if (setjmp(bus_error_jmp) != 0) {
3240 catch_memory_errors = 0;
3241 printf("*** Error dumping task %px\n", tsk);
3245 catch_memory_errors = 1;
3251 for_each_process(tsk)
3256 catch_memory_errors = 0;
3259 static void proccall(void)
3261 unsigned long args[8];
3264 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
3265 unsigned long, unsigned long, unsigned long,
3266 unsigned long, unsigned long, unsigned long);
3269 if (!scanhex(&adrs))
3273 for (i = 0; i < 8; ++i)
3275 for (i = 0; i < 8; ++i) {
3276 if (!scanhex(&args[i]) || termch == '\n')
3280 func = (callfunc_t) adrs;
3282 if (setjmp(bus_error_jmp) == 0) {
3283 catch_memory_errors = 1;
3285 ret = func(args[0], args[1], args[2], args[3],
3286 args[4], args[5], args[6], args[7]);
3288 printf("return value is 0x%lx\n", ret);
3290 printf("*** %x exception occurred\n", fault_except);
3292 catch_memory_errors = 0;
3295 /* Input scanning routines */
3306 while( c == ' ' || c == '\t' )
3312 static const char *regnames[N_PTREGS] = {
3313 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
3314 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
3315 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
3316 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
3317 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
3323 "trap", "dar", "dsisr", "res"
3327 scanhex(unsigned long *vp)
3334 /* parse register name */
3338 for (i = 0; i < sizeof(regname) - 1; ++i) {
3347 i = match_string(regnames, N_PTREGS, regname);
3349 printf("invalid register name '%%%s'\n", regname);
3352 if (xmon_regs == NULL) {
3353 printf("regs not available\n");
3356 *vp = ((unsigned long *)xmon_regs)[i];
3360 /* skip leading "0x" if any */
3374 } else if (c == '$') {
3376 for (i=0; i<63; i++) {
3378 if (isspace(c) || c == '\0') {
3386 if (setjmp(bus_error_jmp) == 0) {
3387 catch_memory_errors = 1;
3389 *vp = kallsyms_lookup_name(tmpstr);
3392 catch_memory_errors = 0;
3394 printf("unknown symbol '%s'\n", tmpstr);
3427 static int hexdigit(int c)
3429 if( '0' <= c && c <= '9' )
3431 if( 'A' <= c && c <= 'F' )
3432 return c - ('A' - 10);
3433 if( 'a' <= c && c <= 'f' )
3434 return c - ('a' - 10);
3439 getstring(char *s, int size)
3455 } while( c != ' ' && c != '\t' && c != '\n' );
3460 static char line[256];
3461 static char *lineptr;
3472 if (lineptr == NULL || *lineptr == 0) {
3473 if (xmon_gets(line, sizeof(line)) == NULL) {
3483 take_input(char *str)
3492 int type = inchar();
3493 unsigned long addr, cpu;
3494 void __percpu *ptr = NULL;
3495 static char tmp[64];
3500 xmon_print_symbol(addr, ": ", "\n");
3505 if (setjmp(bus_error_jmp) == 0) {
3506 catch_memory_errors = 1;
3508 addr = kallsyms_lookup_name(tmp);
3510 printf("%s: %lx\n", tmp, addr);
3512 printf("Symbol '%s' not found.\n", tmp);
3515 catch_memory_errors = 0;
3520 if (setjmp(bus_error_jmp) == 0) {
3521 catch_memory_errors = 1;
3523 ptr = (void __percpu *)kallsyms_lookup_name(tmp);
3528 ptr >= (void __percpu *)__per_cpu_start &&
3529 ptr < (void __percpu *)__per_cpu_end)
3531 if (scanhex(&cpu) && cpu < num_possible_cpus()) {
3532 addr = (unsigned long)per_cpu_ptr(ptr, cpu);
3534 cpu = raw_smp_processor_id();
3535 addr = (unsigned long)this_cpu_ptr(ptr);
3538 printf("%s for cpu 0x%lx: %lx\n", tmp, cpu, addr);
3540 printf("Percpu symbol '%s' not found.\n", tmp);
3543 catch_memory_errors = 0;
3550 /* Print an address in numeric and symbolic form (if possible) */
3551 static void xmon_print_symbol(unsigned long address, const char *mid,
3555 const char *name = NULL;
3556 unsigned long offset, size;
3558 printf(REG, address);
3559 if (setjmp(bus_error_jmp) == 0) {
3560 catch_memory_errors = 1;
3562 name = kallsyms_lookup(address, &size, &offset, &modname,
3565 /* wait a little while to see if we get a machine check */
3569 catch_memory_errors = 0;
3572 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
3574 printf(" [%s]", modname);
3576 printf("%s", after);
3579 #ifdef CONFIG_PPC_BOOK3S_64
3580 void dump_segments(void)
3583 unsigned long esid,vsid;
3586 printf("SLB contents of cpu 0x%x\n", smp_processor_id());
3588 for (i = 0; i < mmu_slb_size; i++) {
3589 asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i));
3590 asm volatile("slbmfev %0,%1" : "=r" (vsid) : "r" (i));
3595 printf("%02d %016lx %016lx", i, esid, vsid);
3597 if (!(esid & SLB_ESID_V)) {
3602 llp = vsid & SLB_VSID_LLP;
3603 if (vsid & SLB_VSID_B_1T) {
3604 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
3606 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T,
3609 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
3611 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT,
3618 #ifdef CONFIG_PPC_BOOK3S_32
3619 void dump_segments(void)
3624 for (i = 0; i < 16; ++i)
3625 printf(" %x", mfsrin(i << 28));
3631 static void dump_tlb_44x(void)
3635 for (i = 0; i < PPC44x_TLB_SIZE; i++) {
3636 unsigned long w0,w1,w2;
3637 asm volatile("tlbre %0,%1,0" : "=r" (w0) : "r" (i));
3638 asm volatile("tlbre %0,%1,1" : "=r" (w1) : "r" (i));
3639 asm volatile("tlbre %0,%1,2" : "=r" (w2) : "r" (i));
3640 printf("[%02x] %08lx %08lx %08lx ", i, w0, w1, w2);
3641 if (w0 & PPC44x_TLB_VALID) {
3642 printf("V %08lx -> %01lx%08lx %c%c%c%c%c",
3643 w0 & PPC44x_TLB_EPN_MASK,
3644 w1 & PPC44x_TLB_ERPN_MASK,
3645 w1 & PPC44x_TLB_RPN_MASK,
3646 (w2 & PPC44x_TLB_W) ? 'W' : 'w',
3647 (w2 & PPC44x_TLB_I) ? 'I' : 'i',
3648 (w2 & PPC44x_TLB_M) ? 'M' : 'm',
3649 (w2 & PPC44x_TLB_G) ? 'G' : 'g',
3650 (w2 & PPC44x_TLB_E) ? 'E' : 'e');
3655 #endif /* CONFIG_44x */
3657 #ifdef CONFIG_PPC_BOOK3E
3658 static void dump_tlb_book3e(void)
3660 u32 mmucfg, pidmask, lpidmask;
3662 int i, tlb, ntlbs, pidsz, lpidsz, rasz, lrat = 0;
3664 static const char *pgsz_names[] = {
3699 /* Gather some infos about the MMU */
3700 mmucfg = mfspr(SPRN_MMUCFG);
3701 mmu_version = (mmucfg & 3) + 1;
3702 ntlbs = ((mmucfg >> 2) & 3) + 1;
3703 pidsz = ((mmucfg >> 6) & 0x1f) + 1;
3704 lpidsz = (mmucfg >> 24) & 0xf;
3705 rasz = (mmucfg >> 16) & 0x7f;
3706 if ((mmu_version > 1) && (mmucfg & 0x10000))
3708 printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n",
3709 mmu_version, ntlbs, pidsz, lpidsz, rasz);
3710 pidmask = (1ul << pidsz) - 1;
3711 lpidmask = (1ul << lpidsz) - 1;
3712 ramask = (1ull << rasz) - 1;
3714 for (tlb = 0; tlb < ntlbs; tlb++) {
3716 int nent, assoc, new_cc = 1;
3717 printf("TLB %d:\n------\n", tlb);
3720 tlbcfg = mfspr(SPRN_TLB0CFG);
3723 tlbcfg = mfspr(SPRN_TLB1CFG);
3726 tlbcfg = mfspr(SPRN_TLB2CFG);
3729 tlbcfg = mfspr(SPRN_TLB3CFG);
3732 printf("Unsupported TLB number !\n");
3735 nent = tlbcfg & 0xfff;
3736 assoc = (tlbcfg >> 24) & 0xff;
3737 for (i = 0; i < nent; i++) {
3738 u32 mas0 = MAS0_TLBSEL(tlb);
3739 u32 mas1 = MAS1_TSIZE(BOOK3E_PAGESZ_4K);
3742 int esel = i, cc = i;
3750 mas0 |= MAS0_ESEL(esel);
3751 mtspr(SPRN_MAS0, mas0);
3752 mtspr(SPRN_MAS1, mas1);
3753 mtspr(SPRN_MAS2, mas2);
3754 asm volatile("tlbre 0,0,0" : : : "memory");
3755 mas1 = mfspr(SPRN_MAS1);
3756 mas2 = mfspr(SPRN_MAS2);
3757 mas7_mas3 = mfspr(SPRN_MAS7_MAS3);
3758 if (assoc && (i % assoc) == 0)
3760 if (!(mas1 & MAS1_VALID))
3763 printf("%04x- ", i);
3765 printf("%04x-%c", cc, 'A' + esel);
3767 printf(" |%c", 'A' + esel);
3769 printf(" %016llx %04x %s %c%c AS%c",
3771 (mas1 >> 16) & 0x3fff,
3772 pgsz_names[(mas1 >> 7) & 0x1f],
3773 mas1 & MAS1_IND ? 'I' : ' ',
3774 mas1 & MAS1_IPROT ? 'P' : ' ',
3775 mas1 & MAS1_TS ? '1' : '0');
3776 printf(" %c%c%c%c%c%c%c",
3777 mas2 & MAS2_X0 ? 'a' : ' ',
3778 mas2 & MAS2_X1 ? 'v' : ' ',
3779 mas2 & MAS2_W ? 'w' : ' ',
3780 mas2 & MAS2_I ? 'i' : ' ',
3781 mas2 & MAS2_M ? 'm' : ' ',
3782 mas2 & MAS2_G ? 'g' : ' ',
3783 mas2 & MAS2_E ? 'e' : ' ');
3784 printf(" %016llx", mas7_mas3 & ramask & ~0x7ffull);
3785 if (mas1 & MAS1_IND)
3787 pgsz_names[(mas7_mas3 >> 1) & 0x1f]);
3789 printf(" U%c%c%c S%c%c%c\n",
3790 mas7_mas3 & MAS3_UX ? 'x' : ' ',
3791 mas7_mas3 & MAS3_UW ? 'w' : ' ',
3792 mas7_mas3 & MAS3_UR ? 'r' : ' ',
3793 mas7_mas3 & MAS3_SX ? 'x' : ' ',
3794 mas7_mas3 & MAS3_SW ? 'w' : ' ',
3795 mas7_mas3 & MAS3_SR ? 'r' : ' ');
3799 #endif /* CONFIG_PPC_BOOK3E */
3801 static void xmon_init(int enable)
3805 __debugger_ipi = xmon_ipi;
3806 __debugger_bpt = xmon_bpt;
3807 __debugger_sstep = xmon_sstep;
3808 __debugger_iabr_match = xmon_iabr_match;
3809 __debugger_break_match = xmon_break_match;
3810 __debugger_fault_handler = xmon_fault_handler;
3812 #ifdef CONFIG_PPC_PSERIES
3814 * Get the token here to avoid trying to get a lock
3815 * during the crash, causing a deadlock.
3817 set_indicator_token = rtas_token("set-indicator");
3821 __debugger_ipi = NULL;
3822 __debugger_bpt = NULL;
3823 __debugger_sstep = NULL;
3824 __debugger_iabr_match = NULL;
3825 __debugger_break_match = NULL;
3826 __debugger_fault_handler = NULL;
3830 #ifdef CONFIG_MAGIC_SYSRQ
3831 static void sysrq_handle_xmon(int key)
3833 if (xmon_is_locked_down()) {
3838 /* ensure xmon is enabled */
3840 debugger(get_irq_regs());
3845 static struct sysrq_key_op sysrq_xmon_op = {
3846 .handler = sysrq_handle_xmon,
3847 .help_msg = "xmon(x)",
3848 .action_msg = "Entering xmon",
3851 static int __init setup_xmon_sysrq(void)
3853 register_sysrq_key('x', &sysrq_xmon_op);
3856 device_initcall(setup_xmon_sysrq);
3857 #endif /* CONFIG_MAGIC_SYSRQ */
3859 static void clear_all_bpt(void)
3863 /* clear/unpatch all breakpoints */
3867 /* Disable all breakpoints */
3868 for (i = 0; i < NBPTS; ++i)
3869 bpts[i].enabled = 0;
3871 /* Clear any data or iabr breakpoints */
3872 if (iabr || dabr.enabled) {
3878 #ifdef CONFIG_DEBUG_FS
3879 static int xmon_dbgfs_set(void *data, u64 val)
3884 /* make sure all breakpoints removed when disabling */
3888 printf("xmon: All breakpoints cleared\n");
3889 release_output_lock();
3895 static int xmon_dbgfs_get(void *data, u64 *val)
3901 DEFINE_SIMPLE_ATTRIBUTE(xmon_dbgfs_ops, xmon_dbgfs_get,
3902 xmon_dbgfs_set, "%llu\n");
3904 static int __init setup_xmon_dbgfs(void)
3906 debugfs_create_file("xmon", 0600, powerpc_debugfs_root, NULL,
3910 device_initcall(setup_xmon_dbgfs);
3911 #endif /* CONFIG_DEBUG_FS */
3913 static int xmon_early __initdata;
3915 static int __init early_parse_xmon(char *p)
3917 if (xmon_is_locked_down()) {
3921 } else if (!p || strncmp(p, "early", 5) == 0) {
3922 /* just "xmon" is equivalent to "xmon=early" */
3926 } else if (strncmp(p, "on", 2) == 0) {
3929 } else if (strncmp(p, "rw", 2) == 0) {
3933 } else if (strncmp(p, "ro", 2) == 0) {
3937 } else if (strncmp(p, "off", 3) == 0)
3944 early_param("xmon", early_parse_xmon);
3946 void __init xmon_setup(void)
3954 #ifdef CONFIG_SPU_BASE
3958 u64 saved_mfc_sr1_RW;
3959 u32 saved_spu_runcntl_RW;
3960 unsigned long dump_addr;
3964 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
3966 static struct spu_info spu_info[XMON_NUM_SPUS];
3968 void xmon_register_spus(struct list_head *list)
3972 list_for_each_entry(spu, list, full_list) {
3973 if (spu->number >= XMON_NUM_SPUS) {
3978 spu_info[spu->number].spu = spu;
3979 spu_info[spu->number].stopped_ok = 0;
3980 spu_info[spu->number].dump_addr = (unsigned long)
3981 spu_info[spu->number].spu->local_store;
3985 static void stop_spus(void)
3991 for (i = 0; i < XMON_NUM_SPUS; i++) {
3992 if (!spu_info[i].spu)
3995 if (setjmp(bus_error_jmp) == 0) {
3996 catch_memory_errors = 1;
3999 spu = spu_info[i].spu;
4001 spu_info[i].saved_spu_runcntl_RW =
4002 in_be32(&spu->problem->spu_runcntl_RW);
4004 tmp = spu_mfc_sr1_get(spu);
4005 spu_info[i].saved_mfc_sr1_RW = tmp;
4007 tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
4008 spu_mfc_sr1_set(spu, tmp);
4013 spu_info[i].stopped_ok = 1;
4015 printf("Stopped spu %.2d (was %s)\n", i,
4016 spu_info[i].saved_spu_runcntl_RW ?
4017 "running" : "stopped");
4019 catch_memory_errors = 0;
4020 printf("*** Error stopping spu %.2d\n", i);
4022 catch_memory_errors = 0;
4026 static void restart_spus(void)
4031 for (i = 0; i < XMON_NUM_SPUS; i++) {
4032 if (!spu_info[i].spu)
4035 if (!spu_info[i].stopped_ok) {
4036 printf("*** Error, spu %d was not successfully stopped"
4037 ", not restarting\n", i);
4041 if (setjmp(bus_error_jmp) == 0) {
4042 catch_memory_errors = 1;
4045 spu = spu_info[i].spu;
4046 spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
4047 out_be32(&spu->problem->spu_runcntl_RW,
4048 spu_info[i].saved_spu_runcntl_RW);
4053 printf("Restarted spu %.2d\n", i);
4055 catch_memory_errors = 0;
4056 printf("*** Error restarting spu %.2d\n", i);
4058 catch_memory_errors = 0;
4062 #define DUMP_WIDTH 23
4063 #define DUMP_VALUE(format, field, value) \
4065 if (setjmp(bus_error_jmp) == 0) { \
4066 catch_memory_errors = 1; \
4068 printf(" %-*s = "format"\n", DUMP_WIDTH, \
4073 catch_memory_errors = 0; \
4074 printf(" %-*s = *** Error reading field.\n", \
4075 DUMP_WIDTH, #field); \
4077 catch_memory_errors = 0; \
4080 #define DUMP_FIELD(obj, format, field) \
4081 DUMP_VALUE(format, field, obj->field)
4083 static void dump_spu_fields(struct spu *spu)
4085 printf("Dumping spu fields at address %p:\n", spu);
4087 DUMP_FIELD(spu, "0x%x", number);
4088 DUMP_FIELD(spu, "%s", name);
4089 DUMP_FIELD(spu, "0x%lx", local_store_phys);
4090 DUMP_FIELD(spu, "0x%p", local_store);
4091 DUMP_FIELD(spu, "0x%lx", ls_size);
4092 DUMP_FIELD(spu, "0x%x", node);
4093 DUMP_FIELD(spu, "0x%lx", flags);
4094 DUMP_FIELD(spu, "%llu", class_0_pending);
4095 DUMP_FIELD(spu, "0x%llx", class_0_dar);
4096 DUMP_FIELD(spu, "0x%llx", class_1_dar);
4097 DUMP_FIELD(spu, "0x%llx", class_1_dsisr);
4098 DUMP_FIELD(spu, "0x%x", irqs[0]);
4099 DUMP_FIELD(spu, "0x%x", irqs[1]);
4100 DUMP_FIELD(spu, "0x%x", irqs[2]);
4101 DUMP_FIELD(spu, "0x%x", slb_replace);
4102 DUMP_FIELD(spu, "%d", pid);
4103 DUMP_FIELD(spu, "0x%p", mm);
4104 DUMP_FIELD(spu, "0x%p", ctx);
4105 DUMP_FIELD(spu, "0x%p", rq);
4106 DUMP_FIELD(spu, "0x%llx", timestamp);
4107 DUMP_FIELD(spu, "0x%lx", problem_phys);
4108 DUMP_FIELD(spu, "0x%p", problem);
4109 DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
4110 in_be32(&spu->problem->spu_runcntl_RW));
4111 DUMP_VALUE("0x%x", problem->spu_status_R,
4112 in_be32(&spu->problem->spu_status_R));
4113 DUMP_VALUE("0x%x", problem->spu_npc_RW,
4114 in_be32(&spu->problem->spu_npc_RW));
4115 DUMP_FIELD(spu, "0x%p", priv2);
4116 DUMP_FIELD(spu, "0x%p", pdata);
4120 spu_inst_dump(unsigned long adr, long count, int praddr)
4122 return generic_inst_dump(adr, count, praddr, print_insn_spu);
4125 static void dump_spu_ls(unsigned long num, int subcmd)
4127 unsigned long offset, addr, ls_addr;
4129 if (setjmp(bus_error_jmp) == 0) {
4130 catch_memory_errors = 1;
4132 ls_addr = (unsigned long)spu_info[num].spu->local_store;
4136 catch_memory_errors = 0;
4137 printf("*** Error: accessing spu info for spu %ld\n", num);
4140 catch_memory_errors = 0;
4142 if (scanhex(&offset))
4143 addr = ls_addr + offset;
4145 addr = spu_info[num].dump_addr;
4147 if (addr >= ls_addr + LS_SIZE) {
4148 printf("*** Error: address outside of local store\n");
4154 addr += spu_inst_dump(addr, 16, 1);
4164 spu_info[num].dump_addr = addr;
4167 static int do_spu_cmd(void)
4169 static unsigned long num = 0;
4170 int cmd, subcmd = 0;
4182 if (isxdigit(subcmd) || subcmd == '\n')
4187 if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
4188 printf("*** Error: invalid spu number\n");
4194 dump_spu_fields(spu_info[num].spu);
4197 dump_spu_ls(num, subcmd);
4208 #else /* ! CONFIG_SPU_BASE */
4209 static int do_spu_cmd(void)