• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Routines providing a simple monitor for use on the PowerMac.
3  *
4  * Copyright (C) 1996-2005 Paul Mackerras.
5  * Copyright (C) 2001 PPC64 Team, IBM Corp
6  * Copyrignt (C) 2006 Michael Ellerman, IBM Corp
7  *
8  *      This program is free software; you can redistribute it and/or
9  *      modify it under the terms of the GNU General Public License
10  *      as published by the Free Software Foundation; either version
11  *      2 of the License, or (at your option) any later version.
12  */
13 
14 #include <linux/kernel.h>
15 #include <linux/errno.h>
16 #include <linux/sched/signal.h>
17 #include <linux/smp.h>
18 #include <linux/mm.h>
19 #include <linux/reboot.h>
20 #include <linux/delay.h>
21 #include <linux/kallsyms.h>
22 #include <linux/kmsg_dump.h>
23 #include <linux/cpumask.h>
24 #include <linux/export.h>
25 #include <linux/sysrq.h>
26 #include <linux/interrupt.h>
27 #include <linux/irq.h>
28 #include <linux/bug.h>
29 #include <linux/nmi.h>
30 #include <linux/ctype.h>
31 #include <linux/highmem.h>
32 
33 #include <asm/debugfs.h>
34 #include <asm/ptrace.h>
35 #include <asm/smp.h>
36 #include <asm/string.h>
37 #include <asm/prom.h>
38 #include <asm/machdep.h>
39 #include <asm/xmon.h>
40 #include <asm/processor.h>
41 #include <asm/pgtable.h>
42 #include <asm/mmu.h>
43 #include <asm/mmu_context.h>
44 #include <asm/plpar_wrappers.h>
45 #include <asm/cputable.h>
46 #include <asm/rtas.h>
47 #include <asm/sstep.h>
48 #include <asm/irq_regs.h>
49 #include <asm/spu.h>
50 #include <asm/spu_priv1.h>
51 #include <asm/setjmp.h>
52 #include <asm/reg.h>
53 #include <asm/debug.h>
54 #include <asm/hw_breakpoint.h>
55 #include <asm/xive.h>
56 #include <asm/opal.h>
57 #include <asm/firmware.h>
58 #include <asm/code-patching.h>
59 #include <asm/sections.h>
60 
61 #ifdef CONFIG_PPC64
62 #include <asm/hvcall.h>
63 #include <asm/paca.h>
64 #endif
65 
66 #include "nonstdio.h"
67 #include "dis-asm.h"
68 
69 #ifdef CONFIG_SMP
70 static cpumask_t cpus_in_xmon = CPU_MASK_NONE;
71 static unsigned long xmon_taken = 1;
72 static int xmon_owner;
73 static int xmon_gate;
74 #else
75 #define xmon_owner 0
76 #endif /* CONFIG_SMP */
77 
78 #ifdef CONFIG_PPC_PSERIES
79 static int set_indicator_token = RTAS_UNKNOWN_SERVICE;
80 #endif
81 static unsigned long in_xmon __read_mostly = 0;
82 static int xmon_on = IS_ENABLED(CONFIG_XMON_DEFAULT);
83 
84 static unsigned long adrs;
85 static int size = 1;
86 #define MAX_DUMP (128 * 1024)
87 static unsigned long ndump = 64;
88 static unsigned long nidump = 16;
89 static unsigned long ncsum = 4096;
90 static int termch;
91 static char tmpstr[128];
92 static int tracing_enabled;
93 
94 static long bus_error_jmp[JMP_BUF_LEN];
95 static int catch_memory_errors;
96 static int catch_spr_faults;
97 static long *xmon_fault_jmp[NR_CPUS];
98 
99 /* Breakpoint stuff */
100 struct bpt {
101 	unsigned long	address;
102 	unsigned int	instr[2];
103 	atomic_t	ref_count;
104 	int		enabled;
105 	unsigned long	pad;
106 };
107 
108 /* Bits in bpt.enabled */
109 #define BP_CIABR	1
110 #define BP_TRAP		2
111 #define BP_DABR		4
112 
113 #define NBPTS	256
114 static struct bpt bpts[NBPTS];
115 static struct bpt dabr;
116 static struct bpt *iabr;
117 static unsigned bpinstr = 0x7fe00008;	/* trap */
118 
119 #define BP_NUM(bp)	((bp) - bpts + 1)
120 
121 /* Prototypes */
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 handle_fault(struct pt_regs *);
126 static void byterev(unsigned char *, int);
127 static void memex(void);
128 static int bsesc(void);
129 static void dump(void);
130 static void show_pte(unsigned long);
131 static void prdump(unsigned long, long);
132 static int ppc_inst_dump(unsigned long, long, int);
133 static void dump_log_buf(void);
134 
135 #ifdef CONFIG_PPC_POWERNV
136 static void dump_opal_msglog(void);
137 #else
dump_opal_msglog(void)138 static inline void dump_opal_msglog(void)
139 {
140 	printf("Machine is not running OPAL firmware.\n");
141 }
142 #endif
143 
144 static void backtrace(struct pt_regs *);
145 static void excprint(struct pt_regs *);
146 static void prregs(struct pt_regs *);
147 static void memops(int);
148 static void memlocate(void);
149 static void memzcan(void);
150 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
151 int skipbl(void);
152 int scanhex(unsigned long *valp);
153 static void scannl(void);
154 static int hexdigit(int);
155 void getstring(char *, int);
156 static void flush_input(void);
157 static int inchar(void);
158 static void take_input(char *);
159 static int  read_spr(int, unsigned long *);
160 static void write_spr(int, unsigned long);
161 static void super_regs(void);
162 static void remove_bpts(void);
163 static void insert_bpts(void);
164 static void remove_cpu_bpts(void);
165 static void insert_cpu_bpts(void);
166 static struct bpt *at_breakpoint(unsigned long pc);
167 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
168 static int  do_step(struct pt_regs *);
169 static void bpt_cmds(void);
170 static void cacheflush(void);
171 static int  cpu_cmd(void);
172 static void csum(void);
173 static void bootcmds(void);
174 static void proccall(void);
175 static void show_tasks(void);
176 void dump_segments(void);
177 static void symbol_lookup(void);
178 static void xmon_show_stack(unsigned long sp, unsigned long lr,
179 			    unsigned long pc);
180 static void xmon_print_symbol(unsigned long address, const char *mid,
181 			      const char *after);
182 static const char *getvecname(unsigned long vec);
183 
184 static int do_spu_cmd(void);
185 
186 #ifdef CONFIG_44x
187 static void dump_tlb_44x(void);
188 #endif
189 #ifdef CONFIG_PPC_BOOK3E
190 static void dump_tlb_book3e(void);
191 #endif
192 
193 #ifdef CONFIG_PPC64
194 #define REG		"%.16lx"
195 #else
196 #define REG		"%.8lx"
197 #endif
198 
199 #ifdef __LITTLE_ENDIAN__
200 #define GETWORD(v)	(((v)[3] << 24) + ((v)[2] << 16) + ((v)[1] << 8) + (v)[0])
201 #else
202 #define GETWORD(v)	(((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
203 #endif
204 
205 static char *help_string = "\
206 Commands:\n\
207   b	show breakpoints\n\
208   bd	set data breakpoint\n\
209   bi	set instruction breakpoint\n\
210   bc	clear breakpoint\n"
211 #ifdef CONFIG_SMP
212   "\
213   c	print cpus stopped in xmon\n\
214   c#	try to switch to cpu number h (in hex)\n"
215 #endif
216   "\
217   C	checksum\n\
218   d	dump bytes\n\
219   d1	dump 1 byte values\n\
220   d2	dump 2 byte values\n\
221   d4	dump 4 byte values\n\
222   d8	dump 8 byte values\n\
223   di	dump instructions\n\
224   df	dump float values\n\
225   dd	dump double values\n\
226   dl    dump the kernel log buffer\n"
227 #ifdef CONFIG_PPC_POWERNV
228   "\
229   do    dump the OPAL message log\n"
230 #endif
231 #ifdef CONFIG_PPC64
232   "\
233   dp[#]	dump paca for current cpu, or cpu #\n\
234   dpa	dump paca for all possible cpus\n"
235 #endif
236   "\
237   dr	dump stream of raw bytes\n\
238   dv	dump virtual address translation \n\
239   dt	dump the tracing buffers (uses printk)\n\
240   dtc	dump the tracing buffers for current CPU (uses printk)\n\
241 "
242 #ifdef CONFIG_PPC_POWERNV
243 "  dx#   dump xive on CPU #\n\
244   dxi#  dump xive irq state #\n\
245   dxa   dump xive on all CPUs\n"
246 #endif
247 "  e	print exception information\n\
248   f	flush cache\n\
249   la	lookup symbol+offset of specified address\n\
250   ls	lookup address of specified symbol\n\
251   lp s [#]	lookup address of percpu symbol s for current cpu, or cpu #\n\
252   m	examine/change memory\n\
253   mm	move a block of memory\n\
254   ms	set a block of memory\n\
255   md	compare two blocks of memory\n\
256   ml	locate a block of memory\n\
257   mz	zero a block of memory\n\
258   mi	show information about memory allocation\n\
259   p 	call a procedure\n\
260   P 	list processes/tasks\n\
261   r	print registers\n\
262   s	single step\n"
263 #ifdef CONFIG_SPU_BASE
264 "  ss	stop execution on all spus\n\
265   sr	restore execution on stopped spus\n\
266   sf  #	dump spu fields for spu # (in hex)\n\
267   sd  #	dump spu local store for spu # (in hex)\n\
268   sdi #	disassemble spu local store for spu # (in hex)\n"
269 #endif
270 "  S	print special registers\n\
271   Sa    print all SPRs\n\
272   Sr #	read SPR #\n\
273   Sw #v write v to SPR #\n\
274   t	print backtrace\n\
275   x	exit monitor and recover\n\
276   X	exit monitor and don't recover\n"
277 #if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_BOOK3E)
278 "  u	dump segment table or SLB\n"
279 #elif defined(CONFIG_PPC_STD_MMU_32)
280 "  u	dump segment registers\n"
281 #elif defined(CONFIG_44x) || defined(CONFIG_PPC_BOOK3E)
282 "  u	dump TLB\n"
283 #endif
284 "  U	show uptime information\n"
285 "  ?	help\n"
286 "  # n	limit output to n lines per page (for dp, dpa, dl)\n"
287 "  zr	reboot\n\
288   zh	halt\n"
289 ;
290 
291 static struct pt_regs *xmon_regs;
292 
sync(void)293 static inline void sync(void)
294 {
295 	asm volatile("sync; isync");
296 }
297 
store_inst(void * p)298 static inline void store_inst(void *p)
299 {
300 	asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
301 }
302 
cflush(void * p)303 static inline void cflush(void *p)
304 {
305 	asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
306 }
307 
cinval(void * p)308 static inline void cinval(void *p)
309 {
310 	asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
311 }
312 
313 /**
314  * write_ciabr() - write the CIABR SPR
315  * @ciabr:	The value to write.
316  *
317  * This function writes a value to the CIARB register either directly
318  * through mtspr instruction if the kernel is in HV privilege mode or
319  * call a hypervisor function to achieve the same in case the kernel
320  * is in supervisor privilege mode.
321  */
write_ciabr(unsigned long ciabr)322 static void write_ciabr(unsigned long ciabr)
323 {
324 	if (!cpu_has_feature(CPU_FTR_ARCH_207S))
325 		return;
326 
327 	if (cpu_has_feature(CPU_FTR_HVMODE)) {
328 		mtspr(SPRN_CIABR, ciabr);
329 		return;
330 	}
331 	plpar_set_ciabr(ciabr);
332 }
333 
334 /**
335  * set_ciabr() - set the CIABR
336  * @addr:	The value to set.
337  *
338  * This function sets the correct privilege value into the the HW
339  * breakpoint address before writing it up in the CIABR register.
340  */
set_ciabr(unsigned long addr)341 static void set_ciabr(unsigned long addr)
342 {
343 	addr &= ~CIABR_PRIV;
344 
345 	if (cpu_has_feature(CPU_FTR_HVMODE))
346 		addr |= CIABR_PRIV_HYPER;
347 	else
348 		addr |= CIABR_PRIV_SUPER;
349 	write_ciabr(addr);
350 }
351 
352 /*
353  * Disable surveillance (the service processor watchdog function)
354  * while we are in xmon.
355  * XXX we should re-enable it when we leave. :)
356  */
357 #define SURVEILLANCE_TOKEN	9000
358 
disable_surveillance(void)359 static inline void disable_surveillance(void)
360 {
361 #ifdef CONFIG_PPC_PSERIES
362 	/* Since this can't be a module, args should end up below 4GB. */
363 	static struct rtas_args args;
364 
365 	/*
366 	 * At this point we have got all the cpus we can into
367 	 * xmon, so there is hopefully no other cpu calling RTAS
368 	 * at the moment, even though we don't take rtas.lock.
369 	 * If we did try to take rtas.lock there would be a
370 	 * real possibility of deadlock.
371 	 */
372 	if (set_indicator_token == RTAS_UNKNOWN_SERVICE)
373 		return;
374 
375 	rtas_call_unlocked(&args, set_indicator_token, 3, 1, NULL,
376 			   SURVEILLANCE_TOKEN, 0, 0);
377 
378 #endif /* CONFIG_PPC_PSERIES */
379 }
380 
381 #ifdef CONFIG_SMP
382 static int xmon_speaker;
383 
get_output_lock(void)384 static void get_output_lock(void)
385 {
386 	int me = smp_processor_id() + 0x100;
387 	int last_speaker = 0, prev;
388 	long timeout;
389 
390 	if (xmon_speaker == me)
391 		return;
392 
393 	for (;;) {
394 		last_speaker = cmpxchg(&xmon_speaker, 0, me);
395 		if (last_speaker == 0)
396 			return;
397 
398 		/*
399 		 * Wait a full second for the lock, we might be on a slow
400 		 * console, but check every 100us.
401 		 */
402 		timeout = 10000;
403 		while (xmon_speaker == last_speaker) {
404 			if (--timeout > 0) {
405 				udelay(100);
406 				continue;
407 			}
408 
409 			/* hostile takeover */
410 			prev = cmpxchg(&xmon_speaker, last_speaker, me);
411 			if (prev == last_speaker)
412 				return;
413 			break;
414 		}
415 	}
416 }
417 
release_output_lock(void)418 static void release_output_lock(void)
419 {
420 	xmon_speaker = 0;
421 }
422 
cpus_are_in_xmon(void)423 int cpus_are_in_xmon(void)
424 {
425 	return !cpumask_empty(&cpus_in_xmon);
426 }
427 
wait_for_other_cpus(int ncpus)428 static bool wait_for_other_cpus(int ncpus)
429 {
430 	unsigned long timeout;
431 
432 	/* We wait for 2s, which is a metric "little while" */
433 	for (timeout = 20000; timeout != 0; --timeout) {
434 		if (cpumask_weight(&cpus_in_xmon) >= ncpus)
435 			return true;
436 		udelay(100);
437 		barrier();
438 	}
439 
440 	return false;
441 }
442 #endif /* CONFIG_SMP */
443 
unrecoverable_excp(struct pt_regs * regs)444 static inline int unrecoverable_excp(struct pt_regs *regs)
445 {
446 #if defined(CONFIG_4xx) || defined(CONFIG_PPC_BOOK3E)
447 	/* We have no MSR_RI bit on 4xx or Book3e, so we simply return false */
448 	return 0;
449 #else
450 	return ((regs->msr & MSR_RI) == 0);
451 #endif
452 }
453 
xmon_core(struct pt_regs * regs,int fromipi)454 static int xmon_core(struct pt_regs *regs, int fromipi)
455 {
456 	int cmd = 0;
457 	struct bpt *bp;
458 	long recurse_jmp[JMP_BUF_LEN];
459 	unsigned long offset;
460 	unsigned long flags;
461 #ifdef CONFIG_SMP
462 	int cpu;
463 	int secondary;
464 #endif
465 
466 	local_irq_save(flags);
467 	hard_irq_disable();
468 
469 	if (!fromipi) {
470 		tracing_enabled = tracing_is_on();
471 		tracing_off();
472 	}
473 
474 	bp = in_breakpoint_table(regs->nip, &offset);
475 	if (bp != NULL) {
476 		regs->nip = bp->address + offset;
477 		atomic_dec(&bp->ref_count);
478 	}
479 
480 	remove_cpu_bpts();
481 
482 #ifdef CONFIG_SMP
483 	cpu = smp_processor_id();
484 	if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
485 		/*
486 		 * We catch SPR read/write faults here because the 0x700, 0xf60
487 		 * etc. handlers don't call debugger_fault_handler().
488 		 */
489 		if (catch_spr_faults)
490 			longjmp(bus_error_jmp, 1);
491 		get_output_lock();
492 		excprint(regs);
493 		printf("cpu 0x%x: Exception %lx %s in xmon, "
494 		       "returning to main loop\n",
495 		       cpu, regs->trap, getvecname(TRAP(regs)));
496 		release_output_lock();
497 		longjmp(xmon_fault_jmp[cpu], 1);
498 	}
499 
500 	if (setjmp(recurse_jmp) != 0) {
501 		if (!in_xmon || !xmon_gate) {
502 			get_output_lock();
503 			printf("xmon: WARNING: bad recursive fault "
504 			       "on cpu 0x%x\n", cpu);
505 			release_output_lock();
506 			goto waiting;
507 		}
508 		secondary = !(xmon_taken && cpu == xmon_owner);
509 		goto cmdloop;
510 	}
511 
512 	xmon_fault_jmp[cpu] = recurse_jmp;
513 
514 	bp = NULL;
515 	if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT))
516 		bp = at_breakpoint(regs->nip);
517 	if (bp || unrecoverable_excp(regs))
518 		fromipi = 0;
519 
520 	if (!fromipi) {
521 		get_output_lock();
522 		excprint(regs);
523 		if (bp) {
524 			printf("cpu 0x%x stopped at breakpoint 0x%tx (",
525 			       cpu, BP_NUM(bp));
526 			xmon_print_symbol(regs->nip, " ", ")\n");
527 		}
528 		if (unrecoverable_excp(regs))
529 			printf("WARNING: exception is not recoverable, "
530 			       "can't continue\n");
531 		release_output_lock();
532 	}
533 
534 	cpumask_set_cpu(cpu, &cpus_in_xmon);
535 
536  waiting:
537 	secondary = 1;
538 	spin_begin();
539 	while (secondary && !xmon_gate) {
540 		if (in_xmon == 0) {
541 			if (fromipi) {
542 				spin_end();
543 				goto leave;
544 			}
545 			secondary = test_and_set_bit(0, &in_xmon);
546 		}
547 		spin_cpu_relax();
548 		touch_nmi_watchdog();
549 	}
550 	spin_end();
551 
552 	if (!secondary && !xmon_gate) {
553 		/* we are the first cpu to come in */
554 		/* interrupt other cpu(s) */
555 		int ncpus = num_online_cpus();
556 
557 		xmon_owner = cpu;
558 		mb();
559 		if (ncpus > 1) {
560 			/*
561 			 * A system reset (trap == 0x100) can be triggered on
562 			 * all CPUs, so when we come in via 0x100 try waiting
563 			 * for the other CPUs to come in before we send the
564 			 * debugger break (IPI). This is similar to
565 			 * crash_kexec_secondary().
566 			 */
567 			if (TRAP(regs) != 0x100 || !wait_for_other_cpus(ncpus))
568 				smp_send_debugger_break();
569 
570 			wait_for_other_cpus(ncpus);
571 		}
572 		remove_bpts();
573 		disable_surveillance();
574 		/* for breakpoint or single step, print the current instr. */
575 		if (bp || TRAP(regs) == 0xd00)
576 			ppc_inst_dump(regs->nip, 1, 0);
577 		printf("enter ? for help\n");
578 		mb();
579 		xmon_gate = 1;
580 		barrier();
581 		touch_nmi_watchdog();
582 	}
583 
584  cmdloop:
585 	while (in_xmon) {
586 		if (secondary) {
587 			spin_begin();
588 			if (cpu == xmon_owner) {
589 				if (!test_and_set_bit(0, &xmon_taken)) {
590 					secondary = 0;
591 					spin_end();
592 					continue;
593 				}
594 				/* missed it */
595 				while (cpu == xmon_owner)
596 					spin_cpu_relax();
597 			}
598 			spin_cpu_relax();
599 			touch_nmi_watchdog();
600 		} else {
601 			cmd = cmds(regs);
602 			if (cmd != 0) {
603 				/* exiting xmon */
604 				insert_bpts();
605 				xmon_gate = 0;
606 				wmb();
607 				in_xmon = 0;
608 				break;
609 			}
610 			/* have switched to some other cpu */
611 			secondary = 1;
612 		}
613 	}
614  leave:
615 	cpumask_clear_cpu(cpu, &cpus_in_xmon);
616 	xmon_fault_jmp[cpu] = NULL;
617 #else
618 	/* UP is simple... */
619 	if (in_xmon) {
620 		printf("Exception %lx %s in xmon, returning to main loop\n",
621 		       regs->trap, getvecname(TRAP(regs)));
622 		longjmp(xmon_fault_jmp[0], 1);
623 	}
624 	if (setjmp(recurse_jmp) == 0) {
625 		xmon_fault_jmp[0] = recurse_jmp;
626 		in_xmon = 1;
627 
628 		excprint(regs);
629 		bp = at_breakpoint(regs->nip);
630 		if (bp) {
631 			printf("Stopped at breakpoint %tx (", BP_NUM(bp));
632 			xmon_print_symbol(regs->nip, " ", ")\n");
633 		}
634 		if (unrecoverable_excp(regs))
635 			printf("WARNING: exception is not recoverable, "
636 			       "can't continue\n");
637 		remove_bpts();
638 		disable_surveillance();
639 		/* for breakpoint or single step, print the current instr. */
640 		if (bp || TRAP(regs) == 0xd00)
641 			ppc_inst_dump(regs->nip, 1, 0);
642 		printf("enter ? for help\n");
643 	}
644 
645 	cmd = cmds(regs);
646 
647 	insert_bpts();
648 	in_xmon = 0;
649 #endif
650 
651 #ifdef CONFIG_BOOKE
652 	if (regs->msr & MSR_DE) {
653 		bp = at_breakpoint(regs->nip);
654 		if (bp != NULL) {
655 			regs->nip = (unsigned long) &bp->instr[0];
656 			atomic_inc(&bp->ref_count);
657 		}
658 	}
659 #else
660 	if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
661 		bp = at_breakpoint(regs->nip);
662 		if (bp != NULL) {
663 			int stepped = emulate_step(regs, bp->instr[0]);
664 			if (stepped == 0) {
665 				regs->nip = (unsigned long) &bp->instr[0];
666 				atomic_inc(&bp->ref_count);
667 			} else if (stepped < 0) {
668 				printf("Couldn't single-step %s instruction\n",
669 				    (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
670 			}
671 		}
672 	}
673 #endif
674 	insert_cpu_bpts();
675 
676 	touch_nmi_watchdog();
677 	local_irq_restore(flags);
678 
679 	return cmd != 'X' && cmd != EOF;
680 }
681 
xmon(struct pt_regs * excp)682 int xmon(struct pt_regs *excp)
683 {
684 	struct pt_regs regs;
685 
686 	if (excp == NULL) {
687 		ppc_save_regs(&regs);
688 		excp = &regs;
689 	}
690 
691 	return xmon_core(excp, 0);
692 }
693 EXPORT_SYMBOL(xmon);
694 
xmon_irq(int irq,void * d)695 irqreturn_t xmon_irq(int irq, void *d)
696 {
697 	unsigned long flags;
698 	local_irq_save(flags);
699 	printf("Keyboard interrupt\n");
700 	xmon(get_irq_regs());
701 	local_irq_restore(flags);
702 	return IRQ_HANDLED;
703 }
704 
xmon_bpt(struct pt_regs * regs)705 static int xmon_bpt(struct pt_regs *regs)
706 {
707 	struct bpt *bp;
708 	unsigned long offset;
709 
710 	if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
711 		return 0;
712 
713 	/* Are we at the trap at bp->instr[1] for some bp? */
714 	bp = in_breakpoint_table(regs->nip, &offset);
715 	if (bp != NULL && offset == 4) {
716 		regs->nip = bp->address + 4;
717 		atomic_dec(&bp->ref_count);
718 		return 1;
719 	}
720 
721 	/* Are we at a breakpoint? */
722 	bp = at_breakpoint(regs->nip);
723 	if (!bp)
724 		return 0;
725 
726 	xmon_core(regs, 0);
727 
728 	return 1;
729 }
730 
xmon_sstep(struct pt_regs * regs)731 static int xmon_sstep(struct pt_regs *regs)
732 {
733 	if (user_mode(regs))
734 		return 0;
735 	xmon_core(regs, 0);
736 	return 1;
737 }
738 
xmon_break_match(struct pt_regs * regs)739 static int xmon_break_match(struct pt_regs *regs)
740 {
741 	if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
742 		return 0;
743 	if (dabr.enabled == 0)
744 		return 0;
745 	xmon_core(regs, 0);
746 	return 1;
747 }
748 
xmon_iabr_match(struct pt_regs * regs)749 static int xmon_iabr_match(struct pt_regs *regs)
750 {
751 	if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
752 		return 0;
753 	if (iabr == NULL)
754 		return 0;
755 	xmon_core(regs, 0);
756 	return 1;
757 }
758 
xmon_ipi(struct pt_regs * regs)759 static int xmon_ipi(struct pt_regs *regs)
760 {
761 #ifdef CONFIG_SMP
762 	if (in_xmon && !cpumask_test_cpu(smp_processor_id(), &cpus_in_xmon))
763 		xmon_core(regs, 1);
764 #endif
765 	return 0;
766 }
767 
xmon_fault_handler(struct pt_regs * regs)768 static int xmon_fault_handler(struct pt_regs *regs)
769 {
770 	struct bpt *bp;
771 	unsigned long offset;
772 
773 	if (in_xmon && catch_memory_errors)
774 		handle_fault(regs);	/* doesn't return */
775 
776 	if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
777 		bp = in_breakpoint_table(regs->nip, &offset);
778 		if (bp != NULL) {
779 			regs->nip = bp->address + offset;
780 			atomic_dec(&bp->ref_count);
781 		}
782 	}
783 
784 	return 0;
785 }
786 
787 /* Force enable xmon if not already enabled */
force_enable_xmon(void)788 static inline void force_enable_xmon(void)
789 {
790 	/* Enable xmon hooks if needed */
791 	if (!xmon_on) {
792 		printf("xmon: Enabling debugger hooks\n");
793 		xmon_on = 1;
794 	}
795 }
796 
at_breakpoint(unsigned long pc)797 static struct bpt *at_breakpoint(unsigned long pc)
798 {
799 	int i;
800 	struct bpt *bp;
801 
802 	bp = bpts;
803 	for (i = 0; i < NBPTS; ++i, ++bp)
804 		if (bp->enabled && pc == bp->address)
805 			return bp;
806 	return NULL;
807 }
808 
in_breakpoint_table(unsigned long nip,unsigned long * offp)809 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
810 {
811 	unsigned long off;
812 
813 	off = nip - (unsigned long) bpts;
814 	if (off >= sizeof(bpts))
815 		return NULL;
816 	off %= sizeof(struct bpt);
817 	if (off != offsetof(struct bpt, instr[0])
818 	    && off != offsetof(struct bpt, instr[1]))
819 		return NULL;
820 	*offp = off - offsetof(struct bpt, instr[0]);
821 	return (struct bpt *) (nip - off);
822 }
823 
new_breakpoint(unsigned long a)824 static struct bpt *new_breakpoint(unsigned long a)
825 {
826 	struct bpt *bp;
827 
828 	a &= ~3UL;
829 	bp = at_breakpoint(a);
830 	if (bp)
831 		return bp;
832 
833 	for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
834 		if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
835 			bp->address = a;
836 			bp->instr[1] = bpinstr;
837 			store_inst(&bp->instr[1]);
838 			return bp;
839 		}
840 	}
841 
842 	printf("Sorry, no free breakpoints.  Please clear one first.\n");
843 	return NULL;
844 }
845 
insert_bpts(void)846 static void insert_bpts(void)
847 {
848 	int i;
849 	struct bpt *bp;
850 
851 	bp = bpts;
852 	for (i = 0; i < NBPTS; ++i, ++bp) {
853 		if ((bp->enabled & (BP_TRAP|BP_CIABR)) == 0)
854 			continue;
855 		if (mread(bp->address, &bp->instr[0], 4) != 4) {
856 			printf("Couldn't read instruction at %lx, "
857 			       "disabling breakpoint there\n", bp->address);
858 			bp->enabled = 0;
859 			continue;
860 		}
861 		if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
862 			printf("Breakpoint at %lx is on an mtmsrd or rfid "
863 			       "instruction, disabling it\n", bp->address);
864 			bp->enabled = 0;
865 			continue;
866 		}
867 		store_inst(&bp->instr[0]);
868 		if (bp->enabled & BP_CIABR)
869 			continue;
870 		if (patch_instruction((unsigned int *)bp->address,
871 							bpinstr) != 0) {
872 			printf("Couldn't write instruction at %lx, "
873 			       "disabling breakpoint there\n", bp->address);
874 			bp->enabled &= ~BP_TRAP;
875 			continue;
876 		}
877 		store_inst((void *)bp->address);
878 	}
879 }
880 
insert_cpu_bpts(void)881 static void insert_cpu_bpts(void)
882 {
883 	struct arch_hw_breakpoint brk;
884 
885 	if (dabr.enabled) {
886 		brk.address = dabr.address;
887 		brk.type = (dabr.enabled & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL;
888 		brk.len = 8;
889 		__set_breakpoint(&brk);
890 	}
891 
892 	if (iabr)
893 		set_ciabr(iabr->address);
894 }
895 
remove_bpts(void)896 static void remove_bpts(void)
897 {
898 	int i;
899 	struct bpt *bp;
900 	unsigned instr;
901 
902 	bp = bpts;
903 	for (i = 0; i < NBPTS; ++i, ++bp) {
904 		if ((bp->enabled & (BP_TRAP|BP_CIABR)) != BP_TRAP)
905 			continue;
906 		if (mread(bp->address, &instr, 4) == 4
907 		    && instr == bpinstr
908 		    && patch_instruction(
909 			(unsigned int *)bp->address, bp->instr[0]) != 0)
910 			printf("Couldn't remove breakpoint at %lx\n",
911 			       bp->address);
912 		else
913 			store_inst((void *)bp->address);
914 	}
915 }
916 
remove_cpu_bpts(void)917 static void remove_cpu_bpts(void)
918 {
919 	hw_breakpoint_disable();
920 	write_ciabr(0);
921 }
922 
923 /* Based on uptime_proc_show(). */
924 static void
show_uptime(void)925 show_uptime(void)
926 {
927 	struct timespec64 uptime;
928 
929 	if (setjmp(bus_error_jmp) == 0) {
930 		catch_memory_errors = 1;
931 		sync();
932 
933 		ktime_get_coarse_boottime_ts64(&uptime);
934 		printf("Uptime: %lu.%.2lu seconds\n", (unsigned long)uptime.tv_sec,
935 			((unsigned long)uptime.tv_nsec / (NSEC_PER_SEC/100)));
936 
937 		sync();
938 		__delay(200);						\
939 	}
940 	catch_memory_errors = 0;
941 }
942 
set_lpp_cmd(void)943 static void set_lpp_cmd(void)
944 {
945 	unsigned long lpp;
946 
947 	if (!scanhex(&lpp)) {
948 		printf("Invalid number.\n");
949 		lpp = 0;
950 	}
951 	xmon_set_pagination_lpp(lpp);
952 }
953 /* Command interpreting routine */
954 static char *last_cmd;
955 
956 static int
cmds(struct pt_regs * excp)957 cmds(struct pt_regs *excp)
958 {
959 	int cmd = 0;
960 
961 	last_cmd = NULL;
962 	xmon_regs = excp;
963 
964 	xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
965 
966 	for(;;) {
967 #ifdef CONFIG_SMP
968 		printf("%x:", smp_processor_id());
969 #endif /* CONFIG_SMP */
970 		printf("mon> ");
971 		flush_input();
972 		termch = 0;
973 		cmd = skipbl();
974 		if( cmd == '\n' ) {
975 			if (last_cmd == NULL)
976 				continue;
977 			take_input(last_cmd);
978 			last_cmd = NULL;
979 			cmd = inchar();
980 		}
981 		switch (cmd) {
982 		case 'm':
983 			cmd = inchar();
984 			switch (cmd) {
985 			case 'm':
986 			case 's':
987 			case 'd':
988 				memops(cmd);
989 				break;
990 			case 'l':
991 				memlocate();
992 				break;
993 			case 'z':
994 				memzcan();
995 				break;
996 			case 'i':
997 				show_mem(0, NULL);
998 				break;
999 			default:
1000 				termch = cmd;
1001 				memex();
1002 			}
1003 			break;
1004 		case 'd':
1005 			dump();
1006 			break;
1007 		case 'l':
1008 			symbol_lookup();
1009 			break;
1010 		case 'r':
1011 			prregs(excp);	/* print regs */
1012 			break;
1013 		case 'e':
1014 			excprint(excp);
1015 			break;
1016 		case 'S':
1017 			super_regs();
1018 			break;
1019 		case 't':
1020 			backtrace(excp);
1021 			break;
1022 		case 'f':
1023 			cacheflush();
1024 			break;
1025 		case 's':
1026 			if (do_spu_cmd() == 0)
1027 				break;
1028 			if (do_step(excp))
1029 				return cmd;
1030 			break;
1031 		case 'x':
1032 		case 'X':
1033 			if (tracing_enabled)
1034 				tracing_on();
1035 			return cmd;
1036 		case EOF:
1037 			printf(" <no input ...>\n");
1038 			mdelay(2000);
1039 			return cmd;
1040 		case '?':
1041 			xmon_puts(help_string);
1042 			break;
1043 		case '#':
1044 			set_lpp_cmd();
1045 			break;
1046 		case 'b':
1047 			bpt_cmds();
1048 			break;
1049 		case 'C':
1050 			csum();
1051 			break;
1052 		case 'c':
1053 			if (cpu_cmd())
1054 				return 0;
1055 			break;
1056 		case 'z':
1057 			bootcmds();
1058 			break;
1059 		case 'p':
1060 			proccall();
1061 			break;
1062 		case 'P':
1063 			show_tasks();
1064 			break;
1065 #ifdef CONFIG_PPC_STD_MMU
1066 		case 'u':
1067 			dump_segments();
1068 			break;
1069 #elif defined(CONFIG_44x)
1070 		case 'u':
1071 			dump_tlb_44x();
1072 			break;
1073 #elif defined(CONFIG_PPC_BOOK3E)
1074 		case 'u':
1075 			dump_tlb_book3e();
1076 			break;
1077 #endif
1078 		case 'U':
1079 			show_uptime();
1080 			break;
1081 		default:
1082 			printf("Unrecognized command: ");
1083 			do {
1084 				if (' ' < cmd && cmd <= '~')
1085 					putchar(cmd);
1086 				else
1087 					printf("\\x%x", cmd);
1088 				cmd = inchar();
1089 			} while (cmd != '\n');
1090 			printf(" (type ? for help)\n");
1091 			break;
1092 		}
1093 	}
1094 }
1095 
1096 #ifdef CONFIG_BOOKE
do_step(struct pt_regs * regs)1097 static int do_step(struct pt_regs *regs)
1098 {
1099 	regs->msr |= MSR_DE;
1100 	mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
1101 	return 1;
1102 }
1103 #else
1104 /*
1105  * Step a single instruction.
1106  * Some instructions we emulate, others we execute with MSR_SE set.
1107  */
do_step(struct pt_regs * regs)1108 static int do_step(struct pt_regs *regs)
1109 {
1110 	unsigned int instr;
1111 	int stepped;
1112 
1113 	force_enable_xmon();
1114 	/* check we are in 64-bit kernel mode, translation enabled */
1115 	if ((regs->msr & (MSR_64BIT|MSR_PR|MSR_IR)) == (MSR_64BIT|MSR_IR)) {
1116 		if (mread(regs->nip, &instr, 4) == 4) {
1117 			stepped = emulate_step(regs, instr);
1118 			if (stepped < 0) {
1119 				printf("Couldn't single-step %s instruction\n",
1120 				       (IS_RFID(instr)? "rfid": "mtmsrd"));
1121 				return 0;
1122 			}
1123 			if (stepped > 0) {
1124 				regs->trap = 0xd00 | (regs->trap & 1);
1125 				printf("stepped to ");
1126 				xmon_print_symbol(regs->nip, " ", "\n");
1127 				ppc_inst_dump(regs->nip, 1, 0);
1128 				return 0;
1129 			}
1130 		}
1131 	}
1132 	regs->msr |= MSR_SE;
1133 	return 1;
1134 }
1135 #endif
1136 
bootcmds(void)1137 static void bootcmds(void)
1138 {
1139 	int cmd;
1140 
1141 	cmd = inchar();
1142 	if (cmd == 'r')
1143 		ppc_md.restart(NULL);
1144 	else if (cmd == 'h')
1145 		ppc_md.halt();
1146 	else if (cmd == 'p')
1147 		if (pm_power_off)
1148 			pm_power_off();
1149 }
1150 
cpu_cmd(void)1151 static int cpu_cmd(void)
1152 {
1153 #ifdef CONFIG_SMP
1154 	unsigned long cpu, first_cpu, last_cpu;
1155 	int timeout;
1156 
1157 	if (!scanhex(&cpu)) {
1158 		/* print cpus waiting or in xmon */
1159 		printf("cpus stopped:");
1160 		last_cpu = first_cpu = NR_CPUS;
1161 		for_each_possible_cpu(cpu) {
1162 			if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
1163 				if (cpu == last_cpu + 1) {
1164 					last_cpu = cpu;
1165 				} else {
1166 					if (last_cpu != first_cpu)
1167 						printf("-0x%lx", last_cpu);
1168 					last_cpu = first_cpu = cpu;
1169 					printf(" 0x%lx", cpu);
1170 				}
1171 			}
1172 		}
1173 		if (last_cpu != first_cpu)
1174 			printf("-0x%lx", last_cpu);
1175 		printf("\n");
1176 		return 0;
1177 	}
1178 	/* try to switch to cpu specified */
1179 	if (!cpumask_test_cpu(cpu, &cpus_in_xmon)) {
1180 		printf("cpu 0x%lx isn't in xmon\n", cpu);
1181 #ifdef CONFIG_PPC64
1182 		printf("backtrace of paca[0x%lx].saved_r1 (possibly stale):\n", cpu);
1183 		xmon_show_stack(paca_ptrs[cpu]->saved_r1, 0, 0);
1184 #endif
1185 		return 0;
1186 	}
1187 	xmon_taken = 0;
1188 	mb();
1189 	xmon_owner = cpu;
1190 	timeout = 10000000;
1191 	while (!xmon_taken) {
1192 		if (--timeout == 0) {
1193 			if (test_and_set_bit(0, &xmon_taken))
1194 				break;
1195 			/* take control back */
1196 			mb();
1197 			xmon_owner = smp_processor_id();
1198 			printf("cpu 0x%lx didn't take control\n", cpu);
1199 			return 0;
1200 		}
1201 		barrier();
1202 	}
1203 	return 1;
1204 #else
1205 	return 0;
1206 #endif /* CONFIG_SMP */
1207 }
1208 
1209 static unsigned short fcstab[256] = {
1210 	0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
1211 	0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
1212 	0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
1213 	0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1214 	0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1215 	0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1216 	0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1217 	0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1218 	0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1219 	0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1220 	0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1221 	0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1222 	0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1223 	0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1224 	0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1225 	0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1226 	0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1227 	0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1228 	0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1229 	0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1230 	0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1231 	0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1232 	0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1233 	0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1234 	0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1235 	0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1236 	0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1237 	0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1238 	0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1239 	0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1240 	0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1241 	0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1242 };
1243 
1244 #define FCS(fcs, c)	(((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1245 
1246 static void
csum(void)1247 csum(void)
1248 {
1249 	unsigned int i;
1250 	unsigned short fcs;
1251 	unsigned char v;
1252 
1253 	if (!scanhex(&adrs))
1254 		return;
1255 	if (!scanhex(&ncsum))
1256 		return;
1257 	fcs = 0xffff;
1258 	for (i = 0; i < ncsum; ++i) {
1259 		if (mread(adrs+i, &v, 1) == 0) {
1260 			printf("csum stopped at "REG"\n", adrs+i);
1261 			break;
1262 		}
1263 		fcs = FCS(fcs, v);
1264 	}
1265 	printf("%x\n", fcs);
1266 }
1267 
1268 /*
1269  * Check if this is a suitable place to put a breakpoint.
1270  */
check_bp_loc(unsigned long addr)1271 static long check_bp_loc(unsigned long addr)
1272 {
1273 	unsigned int instr;
1274 
1275 	addr &= ~3;
1276 	if (!is_kernel_addr(addr)) {
1277 		printf("Breakpoints may only be placed at kernel addresses\n");
1278 		return 0;
1279 	}
1280 	if (!mread(addr, &instr, sizeof(instr))) {
1281 		printf("Can't read instruction at address %lx\n", addr);
1282 		return 0;
1283 	}
1284 	if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1285 		printf("Breakpoints may not be placed on mtmsrd or rfid "
1286 		       "instructions\n");
1287 		return 0;
1288 	}
1289 	return 1;
1290 }
1291 
1292 static char *breakpoint_help_string =
1293     "Breakpoint command usage:\n"
1294     "b                show breakpoints\n"
1295     "b <addr> [cnt]   set breakpoint at given instr addr\n"
1296     "bc               clear all breakpoints\n"
1297     "bc <n/addr>      clear breakpoint number n or at addr\n"
1298     "bi <addr> [cnt]  set hardware instr breakpoint (POWER8 only)\n"
1299     "bd <addr> [cnt]  set hardware data breakpoint\n"
1300     "";
1301 
1302 static void
bpt_cmds(void)1303 bpt_cmds(void)
1304 {
1305 	int cmd;
1306 	unsigned long a;
1307 	int i;
1308 	struct bpt *bp;
1309 
1310 	cmd = inchar();
1311 	switch (cmd) {
1312 #ifndef CONFIG_PPC_8xx
1313 	static const char badaddr[] = "Only kernel addresses are permitted for breakpoints\n";
1314 	int mode;
1315 	case 'd':	/* bd - hardware data breakpoint */
1316 		if (!ppc_breakpoint_available()) {
1317 			printf("Hardware data breakpoint not supported on this cpu\n");
1318 			break;
1319 		}
1320 		mode = 7;
1321 		cmd = inchar();
1322 		if (cmd == 'r')
1323 			mode = 5;
1324 		else if (cmd == 'w')
1325 			mode = 6;
1326 		else
1327 			termch = cmd;
1328 		dabr.address = 0;
1329 		dabr.enabled = 0;
1330 		if (scanhex(&dabr.address)) {
1331 			if (!is_kernel_addr(dabr.address)) {
1332 				printf(badaddr);
1333 				break;
1334 			}
1335 			dabr.address &= ~HW_BRK_TYPE_DABR;
1336 			dabr.enabled = mode | BP_DABR;
1337 		}
1338 
1339 		force_enable_xmon();
1340 		break;
1341 
1342 	case 'i':	/* bi - hardware instr breakpoint */
1343 		if (!cpu_has_feature(CPU_FTR_ARCH_207S)) {
1344 			printf("Hardware instruction breakpoint "
1345 			       "not supported on this cpu\n");
1346 			break;
1347 		}
1348 		if (iabr) {
1349 			iabr->enabled &= ~BP_CIABR;
1350 			iabr = NULL;
1351 		}
1352 		if (!scanhex(&a))
1353 			break;
1354 		if (!check_bp_loc(a))
1355 			break;
1356 		bp = new_breakpoint(a);
1357 		if (bp != NULL) {
1358 			bp->enabled |= BP_CIABR;
1359 			iabr = bp;
1360 			force_enable_xmon();
1361 		}
1362 		break;
1363 #endif
1364 
1365 	case 'c':
1366 		if (!scanhex(&a)) {
1367 			/* clear all breakpoints */
1368 			for (i = 0; i < NBPTS; ++i)
1369 				bpts[i].enabled = 0;
1370 			iabr = NULL;
1371 			dabr.enabled = 0;
1372 			printf("All breakpoints cleared\n");
1373 			break;
1374 		}
1375 
1376 		if (a <= NBPTS && a >= 1) {
1377 			/* assume a breakpoint number */
1378 			bp = &bpts[a-1];	/* bp nums are 1 based */
1379 		} else {
1380 			/* assume a breakpoint address */
1381 			bp = at_breakpoint(a);
1382 			if (bp == NULL) {
1383 				printf("No breakpoint at %lx\n", a);
1384 				break;
1385 			}
1386 		}
1387 
1388 		printf("Cleared breakpoint %tx (", BP_NUM(bp));
1389 		xmon_print_symbol(bp->address, " ", ")\n");
1390 		bp->enabled = 0;
1391 		break;
1392 
1393 	default:
1394 		termch = cmd;
1395 		cmd = skipbl();
1396 		if (cmd == '?') {
1397 			printf(breakpoint_help_string);
1398 			break;
1399 		}
1400 		termch = cmd;
1401 		if (!scanhex(&a)) {
1402 			/* print all breakpoints */
1403 			printf("   type            address\n");
1404 			if (dabr.enabled) {
1405 				printf("   data   "REG"  [", dabr.address);
1406 				if (dabr.enabled & 1)
1407 					printf("r");
1408 				if (dabr.enabled & 2)
1409 					printf("w");
1410 				printf("]\n");
1411 			}
1412 			for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1413 				if (!bp->enabled)
1414 					continue;
1415 				printf("%tx %s   ", BP_NUM(bp),
1416 				    (bp->enabled & BP_CIABR) ? "inst": "trap");
1417 				xmon_print_symbol(bp->address, "  ", "\n");
1418 			}
1419 			break;
1420 		}
1421 
1422 		if (!check_bp_loc(a))
1423 			break;
1424 		bp = new_breakpoint(a);
1425 		if (bp != NULL) {
1426 			bp->enabled |= BP_TRAP;
1427 			force_enable_xmon();
1428 		}
1429 		break;
1430 	}
1431 }
1432 
1433 /* Very cheap human name for vector lookup. */
1434 static
getvecname(unsigned long vec)1435 const char *getvecname(unsigned long vec)
1436 {
1437 	char *ret;
1438 
1439 	switch (vec) {
1440 	case 0x100:	ret = "(System Reset)"; break;
1441 	case 0x200:	ret = "(Machine Check)"; break;
1442 	case 0x300:	ret = "(Data Access)"; break;
1443 	case 0x380:
1444 		if (radix_enabled())
1445 			ret = "(Data Access Out of Range)";
1446 		else
1447 			ret = "(Data SLB Access)";
1448 		break;
1449 	case 0x400:	ret = "(Instruction Access)"; break;
1450 	case 0x480:
1451 		if (radix_enabled())
1452 			ret = "(Instruction Access Out of Range)";
1453 		else
1454 			ret = "(Instruction SLB Access)";
1455 		break;
1456 	case 0x500:	ret = "(Hardware Interrupt)"; break;
1457 	case 0x600:	ret = "(Alignment)"; break;
1458 	case 0x700:	ret = "(Program Check)"; break;
1459 	case 0x800:	ret = "(FPU Unavailable)"; break;
1460 	case 0x900:	ret = "(Decrementer)"; break;
1461 	case 0x980:	ret = "(Hypervisor Decrementer)"; break;
1462 	case 0xa00:	ret = "(Doorbell)"; break;
1463 	case 0xc00:	ret = "(System Call)"; break;
1464 	case 0xd00:	ret = "(Single Step)"; break;
1465 	case 0xe40:	ret = "(Emulation Assist)"; break;
1466 	case 0xe60:	ret = "(HMI)"; break;
1467 	case 0xe80:	ret = "(Hypervisor Doorbell)"; break;
1468 	case 0xf00:	ret = "(Performance Monitor)"; break;
1469 	case 0xf20:	ret = "(Altivec Unavailable)"; break;
1470 	case 0x1300:	ret = "(Instruction Breakpoint)"; break;
1471 	case 0x1500:	ret = "(Denormalisation)"; break;
1472 	case 0x1700:	ret = "(Altivec Assist)"; break;
1473 	default: ret = "";
1474 	}
1475 	return ret;
1476 }
1477 
get_function_bounds(unsigned long pc,unsigned long * startp,unsigned long * endp)1478 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1479 				unsigned long *endp)
1480 {
1481 	unsigned long size, offset;
1482 	const char *name;
1483 
1484 	*startp = *endp = 0;
1485 	if (pc == 0)
1486 		return;
1487 	if (setjmp(bus_error_jmp) == 0) {
1488 		catch_memory_errors = 1;
1489 		sync();
1490 		name = kallsyms_lookup(pc, &size, &offset, NULL, tmpstr);
1491 		if (name != NULL) {
1492 			*startp = pc - offset;
1493 			*endp = pc - offset + size;
1494 		}
1495 		sync();
1496 	}
1497 	catch_memory_errors = 0;
1498 }
1499 
1500 #define LRSAVE_OFFSET		(STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1501 #define MARKER_OFFSET		(STACK_FRAME_MARKER * sizeof(unsigned long))
1502 
xmon_show_stack(unsigned long sp,unsigned long lr,unsigned long pc)1503 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1504 			    unsigned long pc)
1505 {
1506 	int max_to_print = 64;
1507 	unsigned long ip;
1508 	unsigned long newsp;
1509 	unsigned long marker;
1510 	struct pt_regs regs;
1511 
1512 	while (max_to_print--) {
1513 		if (!is_kernel_addr(sp)) {
1514 			if (sp != 0)
1515 				printf("SP (%lx) is in userspace\n", sp);
1516 			break;
1517 		}
1518 
1519 		if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1520 		    || !mread(sp, &newsp, sizeof(unsigned long))) {
1521 			printf("Couldn't read stack frame at %lx\n", sp);
1522 			break;
1523 		}
1524 
1525 		/*
1526 		 * For the first stack frame, try to work out if
1527 		 * LR and/or the saved LR value in the bottommost
1528 		 * stack frame are valid.
1529 		 */
1530 		if ((pc | lr) != 0) {
1531 			unsigned long fnstart, fnend;
1532 			unsigned long nextip;
1533 			int printip = 1;
1534 
1535 			get_function_bounds(pc, &fnstart, &fnend);
1536 			nextip = 0;
1537 			if (newsp > sp)
1538 				mread(newsp + LRSAVE_OFFSET, &nextip,
1539 				      sizeof(unsigned long));
1540 			if (lr == ip) {
1541 				if (!is_kernel_addr(lr)
1542 				    || (fnstart <= lr && lr < fnend))
1543 					printip = 0;
1544 			} else if (lr == nextip) {
1545 				printip = 0;
1546 			} else if (is_kernel_addr(lr)
1547 				   && !(fnstart <= lr && lr < fnend)) {
1548 				printf("[link register   ] ");
1549 				xmon_print_symbol(lr, " ", "\n");
1550 			}
1551 			if (printip) {
1552 				printf("["REG"] ", sp);
1553 				xmon_print_symbol(ip, " ", " (unreliable)\n");
1554 			}
1555 			pc = lr = 0;
1556 
1557 		} else {
1558 			printf("["REG"] ", sp);
1559 			xmon_print_symbol(ip, " ", "\n");
1560 		}
1561 
1562 		/* Look for "regshere" marker to see if this is
1563 		   an exception frame. */
1564 		if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1565 		    && marker == STACK_FRAME_REGS_MARKER) {
1566 			if (mread(sp + STACK_FRAME_OVERHEAD, &regs, sizeof(regs))
1567 			    != sizeof(regs)) {
1568 				printf("Couldn't read registers at %lx\n",
1569 				       sp + STACK_FRAME_OVERHEAD);
1570 				break;
1571 			}
1572 			printf("--- Exception: %lx %s at ", regs.trap,
1573 			       getvecname(TRAP(&regs)));
1574 			pc = regs.nip;
1575 			lr = regs.link;
1576 			xmon_print_symbol(pc, " ", "\n");
1577 		}
1578 
1579 		if (newsp == 0)
1580 			break;
1581 
1582 		sp = newsp;
1583 	}
1584 }
1585 
backtrace(struct pt_regs * excp)1586 static void backtrace(struct pt_regs *excp)
1587 {
1588 	unsigned long sp;
1589 
1590 	if (scanhex(&sp))
1591 		xmon_show_stack(sp, 0, 0);
1592 	else
1593 		xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1594 	scannl();
1595 }
1596 
print_bug_trap(struct pt_regs * regs)1597 static void print_bug_trap(struct pt_regs *regs)
1598 {
1599 #ifdef CONFIG_BUG
1600 	const struct bug_entry *bug;
1601 	unsigned long addr;
1602 
1603 	if (regs->msr & MSR_PR)
1604 		return;		/* not in kernel */
1605 	addr = regs->nip;	/* address of trap instruction */
1606 	if (!is_kernel_addr(addr))
1607 		return;
1608 	bug = find_bug(regs->nip);
1609 	if (bug == NULL)
1610 		return;
1611 	if (is_warning_bug(bug))
1612 		return;
1613 
1614 #ifdef CONFIG_DEBUG_BUGVERBOSE
1615 	printf("kernel BUG at %s:%u!\n",
1616 	       bug->file, bug->line);
1617 #else
1618 	printf("kernel BUG at %px!\n", (void *)bug->bug_addr);
1619 #endif
1620 #endif /* CONFIG_BUG */
1621 }
1622 
excprint(struct pt_regs * fp)1623 static void excprint(struct pt_regs *fp)
1624 {
1625 	unsigned long trap;
1626 
1627 #ifdef CONFIG_SMP
1628 	printf("cpu 0x%x: ", smp_processor_id());
1629 #endif /* CONFIG_SMP */
1630 
1631 	trap = TRAP(fp);
1632 	printf("Vector: %lx %s at [%px]\n", fp->trap, getvecname(trap), fp);
1633 	printf("    pc: ");
1634 	xmon_print_symbol(fp->nip, ": ", "\n");
1635 
1636 	printf("    lr: ");
1637 	xmon_print_symbol(fp->link, ": ", "\n");
1638 
1639 	printf("    sp: %lx\n", fp->gpr[1]);
1640 	printf("   msr: %lx\n", fp->msr);
1641 
1642 	if (trap == 0x300 || trap == 0x380 || trap == 0x600 || trap == 0x200) {
1643 		printf("   dar: %lx\n", fp->dar);
1644 		if (trap != 0x380)
1645 			printf(" dsisr: %lx\n", fp->dsisr);
1646 	}
1647 
1648 	printf("  current = 0x%px\n", current);
1649 #ifdef CONFIG_PPC64
1650 	printf("  paca    = 0x%px\t irqmask: 0x%02x\t irq_happened: 0x%02x\n",
1651 	       local_paca, local_paca->irq_soft_mask, local_paca->irq_happened);
1652 #endif
1653 	if (current) {
1654 		printf("    pid   = %d, comm = %s\n",
1655 		       current->pid, current->comm);
1656 	}
1657 
1658 	if (trap == 0x700)
1659 		print_bug_trap(fp);
1660 
1661 	printf(linux_banner);
1662 }
1663 
prregs(struct pt_regs * fp)1664 static void prregs(struct pt_regs *fp)
1665 {
1666 	int n, trap;
1667 	unsigned long base;
1668 	struct pt_regs regs;
1669 
1670 	if (scanhex(&base)) {
1671 		if (setjmp(bus_error_jmp) == 0) {
1672 			catch_memory_errors = 1;
1673 			sync();
1674 			regs = *(struct pt_regs *)base;
1675 			sync();
1676 			__delay(200);
1677 		} else {
1678 			catch_memory_errors = 0;
1679 			printf("*** Error reading registers from "REG"\n",
1680 			       base);
1681 			return;
1682 		}
1683 		catch_memory_errors = 0;
1684 		fp = &regs;
1685 	}
1686 
1687 #ifdef CONFIG_PPC64
1688 	if (FULL_REGS(fp)) {
1689 		for (n = 0; n < 16; ++n)
1690 			printf("R%.2d = "REG"   R%.2d = "REG"\n",
1691 			       n, fp->gpr[n], n+16, fp->gpr[n+16]);
1692 	} else {
1693 		for (n = 0; n < 7; ++n)
1694 			printf("R%.2d = "REG"   R%.2d = "REG"\n",
1695 			       n, fp->gpr[n], n+7, fp->gpr[n+7]);
1696 	}
1697 #else
1698 	for (n = 0; n < 32; ++n) {
1699 		printf("R%.2d = %.8lx%s", n, fp->gpr[n],
1700 		       (n & 3) == 3? "\n": "   ");
1701 		if (n == 12 && !FULL_REGS(fp)) {
1702 			printf("\n");
1703 			break;
1704 		}
1705 	}
1706 #endif
1707 	printf("pc  = ");
1708 	xmon_print_symbol(fp->nip, " ", "\n");
1709 	if (TRAP(fp) != 0xc00 && cpu_has_feature(CPU_FTR_CFAR)) {
1710 		printf("cfar= ");
1711 		xmon_print_symbol(fp->orig_gpr3, " ", "\n");
1712 	}
1713 	printf("lr  = ");
1714 	xmon_print_symbol(fp->link, " ", "\n");
1715 	printf("msr = "REG"   cr  = %.8lx\n", fp->msr, fp->ccr);
1716 	printf("ctr = "REG"   xer = "REG"   trap = %4lx\n",
1717 	       fp->ctr, fp->xer, fp->trap);
1718 	trap = TRAP(fp);
1719 	if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1720 		printf("dar = "REG"   dsisr = %.8lx\n", fp->dar, fp->dsisr);
1721 }
1722 
cacheflush(void)1723 static void cacheflush(void)
1724 {
1725 	int cmd;
1726 	unsigned long nflush;
1727 
1728 	cmd = inchar();
1729 	if (cmd != 'i')
1730 		termch = cmd;
1731 	scanhex((void *)&adrs);
1732 	if (termch != '\n')
1733 		termch = 0;
1734 	nflush = 1;
1735 	scanhex(&nflush);
1736 	nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1737 	if (setjmp(bus_error_jmp) == 0) {
1738 		catch_memory_errors = 1;
1739 		sync();
1740 
1741 		if (cmd != 'i') {
1742 			for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1743 				cflush((void *) adrs);
1744 		} else {
1745 			for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1746 				cinval((void *) adrs);
1747 		}
1748 		sync();
1749 		/* wait a little while to see if we get a machine check */
1750 		__delay(200);
1751 	}
1752 	catch_memory_errors = 0;
1753 }
1754 
1755 extern unsigned long xmon_mfspr(int spr, unsigned long default_value);
1756 extern void xmon_mtspr(int spr, unsigned long value);
1757 
1758 static int
read_spr(int n,unsigned long * vp)1759 read_spr(int n, unsigned long *vp)
1760 {
1761 	unsigned long ret = -1UL;
1762 	int ok = 0;
1763 
1764 	if (setjmp(bus_error_jmp) == 0) {
1765 		catch_spr_faults = 1;
1766 		sync();
1767 
1768 		ret = xmon_mfspr(n, *vp);
1769 
1770 		sync();
1771 		*vp = ret;
1772 		ok = 1;
1773 	}
1774 	catch_spr_faults = 0;
1775 
1776 	return ok;
1777 }
1778 
1779 static void
write_spr(int n,unsigned long val)1780 write_spr(int n, unsigned long val)
1781 {
1782 	if (setjmp(bus_error_jmp) == 0) {
1783 		catch_spr_faults = 1;
1784 		sync();
1785 
1786 		xmon_mtspr(n, val);
1787 
1788 		sync();
1789 	} else {
1790 		printf("SPR 0x%03x (%4d) Faulted during write\n", n, n);
1791 	}
1792 	catch_spr_faults = 0;
1793 }
1794 
dump_206_sprs(void)1795 static void dump_206_sprs(void)
1796 {
1797 #ifdef CONFIG_PPC64
1798 	if (!cpu_has_feature(CPU_FTR_ARCH_206))
1799 		return;
1800 
1801 	/* Actually some of these pre-date 2.06, but whatevs */
1802 
1803 	printf("srr0   = %.16lx  srr1  = %.16lx dsisr  = %.8lx\n",
1804 		mfspr(SPRN_SRR0), mfspr(SPRN_SRR1), mfspr(SPRN_DSISR));
1805 	printf("dscr   = %.16lx  ppr   = %.16lx pir    = %.8lx\n",
1806 		mfspr(SPRN_DSCR), mfspr(SPRN_PPR), mfspr(SPRN_PIR));
1807 	printf("amr    = %.16lx  uamor = %.16lx\n",
1808 		mfspr(SPRN_AMR), mfspr(SPRN_UAMOR));
1809 
1810 	if (!(mfmsr() & MSR_HV))
1811 		return;
1812 
1813 	printf("sdr1   = %.16lx  hdar  = %.16lx hdsisr = %.8lx\n",
1814 		mfspr(SPRN_SDR1), mfspr(SPRN_HDAR), mfspr(SPRN_HDSISR));
1815 	printf("hsrr0  = %.16lx hsrr1  = %.16lx hdec   = %.16lx\n",
1816 		mfspr(SPRN_HSRR0), mfspr(SPRN_HSRR1), mfspr(SPRN_HDEC));
1817 	printf("lpcr   = %.16lx  pcr   = %.16lx lpidr  = %.8lx\n",
1818 		mfspr(SPRN_LPCR), mfspr(SPRN_PCR), mfspr(SPRN_LPID));
1819 	printf("hsprg0 = %.16lx hsprg1 = %.16lx amor   = %.16lx\n",
1820 		mfspr(SPRN_HSPRG0), mfspr(SPRN_HSPRG1), mfspr(SPRN_AMOR));
1821 	printf("dabr   = %.16lx dabrx  = %.16lx\n",
1822 		mfspr(SPRN_DABR), mfspr(SPRN_DABRX));
1823 #endif
1824 }
1825 
dump_207_sprs(void)1826 static void dump_207_sprs(void)
1827 {
1828 #ifdef CONFIG_PPC64
1829 	unsigned long msr;
1830 
1831 	if (!cpu_has_feature(CPU_FTR_ARCH_207S))
1832 		return;
1833 
1834 	printf("dpdes  = %.16lx  tir   = %.16lx cir    = %.8lx\n",
1835 		mfspr(SPRN_DPDES), mfspr(SPRN_TIR), mfspr(SPRN_CIR));
1836 
1837 	printf("fscr   = %.16lx  tar   = %.16lx pspb   = %.8lx\n",
1838 		mfspr(SPRN_FSCR), mfspr(SPRN_TAR), mfspr(SPRN_PSPB));
1839 
1840 	msr = mfmsr();
1841 	if (msr & MSR_TM) {
1842 		/* Only if TM has been enabled in the kernel */
1843 		printf("tfhar  = %.16lx  tfiar = %.16lx texasr = %.16lx\n",
1844 			mfspr(SPRN_TFHAR), mfspr(SPRN_TFIAR),
1845 			mfspr(SPRN_TEXASR));
1846 	}
1847 
1848 	printf("mmcr0  = %.16lx  mmcr1 = %.16lx mmcr2  = %.16lx\n",
1849 		mfspr(SPRN_MMCR0), mfspr(SPRN_MMCR1), mfspr(SPRN_MMCR2));
1850 	printf("pmc1   = %.8lx pmc2 = %.8lx  pmc3 = %.8lx  pmc4   = %.8lx\n",
1851 		mfspr(SPRN_PMC1), mfspr(SPRN_PMC2),
1852 		mfspr(SPRN_PMC3), mfspr(SPRN_PMC4));
1853 	printf("mmcra  = %.16lx   siar = %.16lx pmc5   = %.8lx\n",
1854 		mfspr(SPRN_MMCRA), mfspr(SPRN_SIAR), mfspr(SPRN_PMC5));
1855 	printf("sdar   = %.16lx   sier = %.16lx pmc6   = %.8lx\n",
1856 		mfspr(SPRN_SDAR), mfspr(SPRN_SIER), mfspr(SPRN_PMC6));
1857 	printf("ebbhr  = %.16lx  ebbrr = %.16lx bescr  = %.16lx\n",
1858 		mfspr(SPRN_EBBHR), mfspr(SPRN_EBBRR), mfspr(SPRN_BESCR));
1859 	printf("iamr   = %.16lx\n", mfspr(SPRN_IAMR));
1860 
1861 	if (!(msr & MSR_HV))
1862 		return;
1863 
1864 	printf("hfscr  = %.16lx  dhdes = %.16lx rpr    = %.16lx\n",
1865 		mfspr(SPRN_HFSCR), mfspr(SPRN_DHDES), mfspr(SPRN_RPR));
1866 	printf("dawr   = %.16lx  dawrx = %.16lx ciabr  = %.16lx\n",
1867 		mfspr(SPRN_DAWR), mfspr(SPRN_DAWRX), mfspr(SPRN_CIABR));
1868 #endif
1869 }
1870 
dump_300_sprs(void)1871 static void dump_300_sprs(void)
1872 {
1873 #ifdef CONFIG_PPC64
1874 	bool hv = mfmsr() & MSR_HV;
1875 
1876 	if (!cpu_has_feature(CPU_FTR_ARCH_300))
1877 		return;
1878 
1879 	printf("pidr   = %.16lx  tidr  = %.16lx\n",
1880 		mfspr(SPRN_PID), mfspr(SPRN_TIDR));
1881 	printf("psscr  = %.16lx\n",
1882 		hv ? mfspr(SPRN_PSSCR) : mfspr(SPRN_PSSCR_PR));
1883 
1884 	if (!hv)
1885 		return;
1886 
1887 	printf("ptcr   = %.16lx  asdr  = %.16lx\n",
1888 		mfspr(SPRN_PTCR), mfspr(SPRN_ASDR));
1889 #endif
1890 }
1891 
dump_one_spr(int spr,bool show_unimplemented)1892 static void dump_one_spr(int spr, bool show_unimplemented)
1893 {
1894 	unsigned long val;
1895 
1896 	val = 0xdeadbeef;
1897 	if (!read_spr(spr, &val)) {
1898 		printf("SPR 0x%03x (%4d) Faulted during read\n", spr, spr);
1899 		return;
1900 	}
1901 
1902 	if (val == 0xdeadbeef) {
1903 		/* Looks like read was a nop, confirm */
1904 		val = 0x0badcafe;
1905 		if (!read_spr(spr, &val)) {
1906 			printf("SPR 0x%03x (%4d) Faulted during read\n", spr, spr);
1907 			return;
1908 		}
1909 
1910 		if (val == 0x0badcafe) {
1911 			if (show_unimplemented)
1912 				printf("SPR 0x%03x (%4d) Unimplemented\n", spr, spr);
1913 			return;
1914 		}
1915 	}
1916 
1917 	printf("SPR 0x%03x (%4d) = 0x%lx\n", spr, spr, val);
1918 }
1919 
super_regs(void)1920 static void super_regs(void)
1921 {
1922 	static unsigned long regno;
1923 	int cmd;
1924 	int spr;
1925 
1926 	cmd = skipbl();
1927 
1928 	switch (cmd) {
1929 	case '\n': {
1930 		unsigned long sp, toc;
1931 		asm("mr %0,1" : "=r" (sp) :);
1932 		asm("mr %0,2" : "=r" (toc) :);
1933 
1934 		printf("msr    = "REG"  sprg0 = "REG"\n",
1935 		       mfmsr(), mfspr(SPRN_SPRG0));
1936 		printf("pvr    = "REG"  sprg1 = "REG"\n",
1937 		       mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
1938 		printf("dec    = "REG"  sprg2 = "REG"\n",
1939 		       mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1940 		printf("sp     = "REG"  sprg3 = "REG"\n", sp, mfspr(SPRN_SPRG3));
1941 		printf("toc    = "REG"  dar   = "REG"\n", toc, mfspr(SPRN_DAR));
1942 
1943 		dump_206_sprs();
1944 		dump_207_sprs();
1945 		dump_300_sprs();
1946 
1947 		return;
1948 	}
1949 	case 'w': {
1950 		unsigned long val;
1951 		scanhex(&regno);
1952 		val = 0;
1953 		read_spr(regno, &val);
1954 		scanhex(&val);
1955 		write_spr(regno, val);
1956 		dump_one_spr(regno, true);
1957 		break;
1958 	}
1959 	case 'r':
1960 		scanhex(&regno);
1961 		dump_one_spr(regno, true);
1962 		break;
1963 	case 'a':
1964 		/* dump ALL SPRs */
1965 		for (spr = 1; spr < 1024; ++spr)
1966 			dump_one_spr(spr, false);
1967 		break;
1968 	}
1969 
1970 	scannl();
1971 }
1972 
1973 /*
1974  * Stuff for reading and writing memory safely
1975  */
1976 static int
mread(unsigned long adrs,void * buf,int size)1977 mread(unsigned long adrs, void *buf, int size)
1978 {
1979 	volatile int n;
1980 	char *p, *q;
1981 
1982 	n = 0;
1983 	if (setjmp(bus_error_jmp) == 0) {
1984 		catch_memory_errors = 1;
1985 		sync();
1986 		p = (char *)adrs;
1987 		q = (char *)buf;
1988 		switch (size) {
1989 		case 2:
1990 			*(u16 *)q = *(u16 *)p;
1991 			break;
1992 		case 4:
1993 			*(u32 *)q = *(u32 *)p;
1994 			break;
1995 		case 8:
1996 			*(u64 *)q = *(u64 *)p;
1997 			break;
1998 		default:
1999 			for( ; n < size; ++n) {
2000 				*q++ = *p++;
2001 				sync();
2002 			}
2003 		}
2004 		sync();
2005 		/* wait a little while to see if we get a machine check */
2006 		__delay(200);
2007 		n = size;
2008 	}
2009 	catch_memory_errors = 0;
2010 	return n;
2011 }
2012 
2013 static int
mwrite(unsigned long adrs,void * buf,int size)2014 mwrite(unsigned long adrs, void *buf, int size)
2015 {
2016 	volatile int n;
2017 	char *p, *q;
2018 
2019 	n = 0;
2020 	if (setjmp(bus_error_jmp) == 0) {
2021 		catch_memory_errors = 1;
2022 		sync();
2023 		p = (char *) adrs;
2024 		q = (char *) buf;
2025 		switch (size) {
2026 		case 2:
2027 			*(u16 *)p = *(u16 *)q;
2028 			break;
2029 		case 4:
2030 			*(u32 *)p = *(u32 *)q;
2031 			break;
2032 		case 8:
2033 			*(u64 *)p = *(u64 *)q;
2034 			break;
2035 		default:
2036 			for ( ; n < size; ++n) {
2037 				*p++ = *q++;
2038 				sync();
2039 			}
2040 		}
2041 		sync();
2042 		/* wait a little while to see if we get a machine check */
2043 		__delay(200);
2044 		n = size;
2045 	} else {
2046 		printf("*** Error writing address "REG"\n", adrs + n);
2047 	}
2048 	catch_memory_errors = 0;
2049 	return n;
2050 }
2051 
2052 static int fault_type;
2053 static int fault_except;
2054 static char *fault_chars[] = { "--", "**", "##" };
2055 
handle_fault(struct pt_regs * regs)2056 static int handle_fault(struct pt_regs *regs)
2057 {
2058 	fault_except = TRAP(regs);
2059 	switch (TRAP(regs)) {
2060 	case 0x200:
2061 		fault_type = 0;
2062 		break;
2063 	case 0x300:
2064 	case 0x380:
2065 		fault_type = 1;
2066 		break;
2067 	default:
2068 		fault_type = 2;
2069 	}
2070 
2071 	longjmp(bus_error_jmp, 1);
2072 
2073 	return 0;
2074 }
2075 
2076 #define SWAP(a, b, t)	((t) = (a), (a) = (b), (b) = (t))
2077 
2078 static void
byterev(unsigned char * val,int size)2079 byterev(unsigned char *val, int size)
2080 {
2081 	int t;
2082 
2083 	switch (size) {
2084 	case 2:
2085 		SWAP(val[0], val[1], t);
2086 		break;
2087 	case 4:
2088 		SWAP(val[0], val[3], t);
2089 		SWAP(val[1], val[2], t);
2090 		break;
2091 	case 8: /* is there really any use for this? */
2092 		SWAP(val[0], val[7], t);
2093 		SWAP(val[1], val[6], t);
2094 		SWAP(val[2], val[5], t);
2095 		SWAP(val[3], val[4], t);
2096 		break;
2097 	}
2098 }
2099 
2100 static int brev;
2101 static int mnoread;
2102 
2103 static char *memex_help_string =
2104     "Memory examine command usage:\n"
2105     "m [addr] [flags] examine/change memory\n"
2106     "  addr is optional.  will start where left off.\n"
2107     "  flags may include chars from this set:\n"
2108     "    b   modify by bytes (default)\n"
2109     "    w   modify by words (2 byte)\n"
2110     "    l   modify by longs (4 byte)\n"
2111     "    d   modify by doubleword (8 byte)\n"
2112     "    r   toggle reverse byte order mode\n"
2113     "    n   do not read memory (for i/o spaces)\n"
2114     "    .   ok to read (default)\n"
2115     "NOTE: flags are saved as defaults\n"
2116     "";
2117 
2118 static char *memex_subcmd_help_string =
2119     "Memory examine subcommands:\n"
2120     "  hexval   write this val to current location\n"
2121     "  'string' write chars from string to this location\n"
2122     "  '        increment address\n"
2123     "  ^        decrement address\n"
2124     "  /        increment addr by 0x10.  //=0x100, ///=0x1000, etc\n"
2125     "  \\        decrement addr by 0x10.  \\\\=0x100, \\\\\\=0x1000, etc\n"
2126     "  `        clear no-read flag\n"
2127     "  ;        stay at this addr\n"
2128     "  v        change to byte mode\n"
2129     "  w        change to word (2 byte) mode\n"
2130     "  l        change to long (4 byte) mode\n"
2131     "  u        change to doubleword (8 byte) mode\n"
2132     "  m addr   change current addr\n"
2133     "  n        toggle no-read flag\n"
2134     "  r        toggle byte reverse flag\n"
2135     "  < count  back up count bytes\n"
2136     "  > count  skip forward count bytes\n"
2137     "  x        exit this mode\n"
2138     "";
2139 
2140 static void
memex(void)2141 memex(void)
2142 {
2143 	int cmd, inc, i, nslash;
2144 	unsigned long n;
2145 	unsigned char val[16];
2146 
2147 	scanhex((void *)&adrs);
2148 	cmd = skipbl();
2149 	if (cmd == '?') {
2150 		printf(memex_help_string);
2151 		return;
2152 	} else {
2153 		termch = cmd;
2154 	}
2155 	last_cmd = "m\n";
2156 	while ((cmd = skipbl()) != '\n') {
2157 		switch( cmd ){
2158 		case 'b':	size = 1;	break;
2159 		case 'w':	size = 2;	break;
2160 		case 'l':	size = 4;	break;
2161 		case 'd':	size = 8;	break;
2162 		case 'r': 	brev = !brev;	break;
2163 		case 'n':	mnoread = 1;	break;
2164 		case '.':	mnoread = 0;	break;
2165 		}
2166 	}
2167 	if( size <= 0 )
2168 		size = 1;
2169 	else if( size > 8 )
2170 		size = 8;
2171 	for(;;){
2172 		if (!mnoread)
2173 			n = mread(adrs, val, size);
2174 		printf(REG"%c", adrs, brev? 'r': ' ');
2175 		if (!mnoread) {
2176 			if (brev)
2177 				byterev(val, size);
2178 			putchar(' ');
2179 			for (i = 0; i < n; ++i)
2180 				printf("%.2x", val[i]);
2181 			for (; i < size; ++i)
2182 				printf("%s", fault_chars[fault_type]);
2183 		}
2184 		putchar(' ');
2185 		inc = size;
2186 		nslash = 0;
2187 		for(;;){
2188 			if( scanhex(&n) ){
2189 				for (i = 0; i < size; ++i)
2190 					val[i] = n >> (i * 8);
2191 				if (!brev)
2192 					byterev(val, size);
2193 				mwrite(adrs, val, size);
2194 				inc = size;
2195 			}
2196 			cmd = skipbl();
2197 			if (cmd == '\n')
2198 				break;
2199 			inc = 0;
2200 			switch (cmd) {
2201 			case '\'':
2202 				for(;;){
2203 					n = inchar();
2204 					if( n == '\\' )
2205 						n = bsesc();
2206 					else if( n == '\'' )
2207 						break;
2208 					for (i = 0; i < size; ++i)
2209 						val[i] = n >> (i * 8);
2210 					if (!brev)
2211 						byterev(val, size);
2212 					mwrite(adrs, val, size);
2213 					adrs += size;
2214 				}
2215 				adrs -= size;
2216 				inc = size;
2217 				break;
2218 			case ',':
2219 				adrs += size;
2220 				break;
2221 			case '.':
2222 				mnoread = 0;
2223 				break;
2224 			case ';':
2225 				break;
2226 			case 'x':
2227 			case EOF:
2228 				scannl();
2229 				return;
2230 			case 'b':
2231 			case 'v':
2232 				size = 1;
2233 				break;
2234 			case 'w':
2235 				size = 2;
2236 				break;
2237 			case 'l':
2238 				size = 4;
2239 				break;
2240 			case 'u':
2241 				size = 8;
2242 				break;
2243 			case '^':
2244 				adrs -= size;
2245 				break;
2246 			case '/':
2247 				if (nslash > 0)
2248 					adrs -= 1 << nslash;
2249 				else
2250 					nslash = 0;
2251 				nslash += 4;
2252 				adrs += 1 << nslash;
2253 				break;
2254 			case '\\':
2255 				if (nslash < 0)
2256 					adrs += 1 << -nslash;
2257 				else
2258 					nslash = 0;
2259 				nslash -= 4;
2260 				adrs -= 1 << -nslash;
2261 				break;
2262 			case 'm':
2263 				scanhex((void *)&adrs);
2264 				break;
2265 			case 'n':
2266 				mnoread = 1;
2267 				break;
2268 			case 'r':
2269 				brev = !brev;
2270 				break;
2271 			case '<':
2272 				n = size;
2273 				scanhex(&n);
2274 				adrs -= n;
2275 				break;
2276 			case '>':
2277 				n = size;
2278 				scanhex(&n);
2279 				adrs += n;
2280 				break;
2281 			case '?':
2282 				printf(memex_subcmd_help_string);
2283 				break;
2284 			}
2285 		}
2286 		adrs += inc;
2287 	}
2288 }
2289 
2290 static int
bsesc(void)2291 bsesc(void)
2292 {
2293 	int c;
2294 
2295 	c = inchar();
2296 	switch( c ){
2297 	case 'n':	c = '\n';	break;
2298 	case 'r':	c = '\r';	break;
2299 	case 'b':	c = '\b';	break;
2300 	case 't':	c = '\t';	break;
2301 	}
2302 	return c;
2303 }
2304 
xmon_rawdump(unsigned long adrs,long ndump)2305 static void xmon_rawdump (unsigned long adrs, long ndump)
2306 {
2307 	long n, m, r, nr;
2308 	unsigned char temp[16];
2309 
2310 	for (n = ndump; n > 0;) {
2311 		r = n < 16? n: 16;
2312 		nr = mread(adrs, temp, r);
2313 		adrs += nr;
2314 		for (m = 0; m < r; ++m) {
2315 			if (m < nr)
2316 				printf("%.2x", temp[m]);
2317 			else
2318 				printf("%s", fault_chars[fault_type]);
2319 		}
2320 		n -= r;
2321 		if (nr < r)
2322 			break;
2323 	}
2324 	printf("\n");
2325 }
2326 
dump_tracing(void)2327 static void dump_tracing(void)
2328 {
2329 	int c;
2330 
2331 	c = inchar();
2332 	if (c == 'c')
2333 		ftrace_dump(DUMP_ORIG);
2334 	else
2335 		ftrace_dump(DUMP_ALL);
2336 }
2337 
2338 #ifdef CONFIG_PPC64
dump_one_paca(int cpu)2339 static void dump_one_paca(int cpu)
2340 {
2341 	struct paca_struct *p;
2342 #ifdef CONFIG_PPC_BOOK3S_64
2343 	int i = 0;
2344 #endif
2345 
2346 	if (setjmp(bus_error_jmp) != 0) {
2347 		printf("*** Error dumping paca for cpu 0x%x!\n", cpu);
2348 		return;
2349 	}
2350 
2351 	catch_memory_errors = 1;
2352 	sync();
2353 
2354 	p = paca_ptrs[cpu];
2355 
2356 	printf("paca for cpu 0x%x @ %px:\n", cpu, p);
2357 
2358 	printf(" %-*s = %s\n", 25, "possible", cpu_possible(cpu) ? "yes" : "no");
2359 	printf(" %-*s = %s\n", 25, "present", cpu_present(cpu) ? "yes" : "no");
2360 	printf(" %-*s = %s\n", 25, "online", cpu_online(cpu) ? "yes" : "no");
2361 
2362 #define DUMP(paca, name, format)				\
2363 	printf(" %-*s = "format"\t(0x%lx)\n", 25, #name, 18, paca->name, \
2364 		offsetof(struct paca_struct, name));
2365 
2366 	DUMP(p, lock_token, "%#-*x");
2367 	DUMP(p, paca_index, "%#-*x");
2368 	DUMP(p, kernel_toc, "%#-*llx");
2369 	DUMP(p, kernelbase, "%#-*llx");
2370 	DUMP(p, kernel_msr, "%#-*llx");
2371 	DUMP(p, emergency_sp, "%-*px");
2372 #ifdef CONFIG_PPC_BOOK3S_64
2373 	DUMP(p, nmi_emergency_sp, "%-*px");
2374 	DUMP(p, mc_emergency_sp, "%-*px");
2375 	DUMP(p, in_nmi, "%#-*x");
2376 	DUMP(p, in_mce, "%#-*x");
2377 	DUMP(p, hmi_event_available, "%#-*x");
2378 #endif
2379 	DUMP(p, data_offset, "%#-*llx");
2380 	DUMP(p, hw_cpu_id, "%#-*x");
2381 	DUMP(p, cpu_start, "%#-*x");
2382 	DUMP(p, kexec_state, "%#-*x");
2383 #ifdef CONFIG_PPC_BOOK3S_64
2384 	for (i = 0; i < SLB_NUM_BOLTED; i++) {
2385 		u64 esid, vsid;
2386 
2387 		if (!p->slb_shadow_ptr)
2388 			continue;
2389 
2390 		esid = be64_to_cpu(p->slb_shadow_ptr->save_area[i].esid);
2391 		vsid = be64_to_cpu(p->slb_shadow_ptr->save_area[i].vsid);
2392 
2393 		if (esid || vsid) {
2394 			printf(" %-*s[%d] = 0x%016llx 0x%016llx\n",
2395 			       22, "slb_shadow", i, esid, vsid);
2396 		}
2397 	}
2398 	DUMP(p, vmalloc_sllp, "%#-*x");
2399 	DUMP(p, slb_cache_ptr, "%#-*x");
2400 	for (i = 0; i < SLB_CACHE_ENTRIES; i++)
2401 		printf(" %-*s[%d] = 0x%016x\n",
2402 		       22, "slb_cache", i, p->slb_cache[i]);
2403 
2404 	DUMP(p, rfi_flush_fallback_area, "%-*px");
2405 #endif
2406 	DUMP(p, dscr_default, "%#-*llx");
2407 #ifdef CONFIG_PPC_BOOK3E
2408 	DUMP(p, pgd, "%-*px");
2409 	DUMP(p, kernel_pgd, "%-*px");
2410 	DUMP(p, tcd_ptr, "%-*px");
2411 	DUMP(p, mc_kstack, "%-*px");
2412 	DUMP(p, crit_kstack, "%-*px");
2413 	DUMP(p, dbg_kstack, "%-*px");
2414 #endif
2415 	DUMP(p, __current, "%-*px");
2416 	DUMP(p, kstack, "%#-*llx");
2417 	printf(" %-*s = 0x%016llx\n", 25, "kstack_base", p->kstack & ~(THREAD_SIZE - 1));
2418 	DUMP(p, stab_rr, "%#-*llx");
2419 	DUMP(p, saved_r1, "%#-*llx");
2420 	DUMP(p, trap_save, "%#-*x");
2421 	DUMP(p, irq_soft_mask, "%#-*x");
2422 	DUMP(p, irq_happened, "%#-*x");
2423 	DUMP(p, io_sync, "%#-*x");
2424 	DUMP(p, irq_work_pending, "%#-*x");
2425 	DUMP(p, nap_state_lost, "%#-*x");
2426 	DUMP(p, sprg_vdso, "%#-*llx");
2427 
2428 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
2429 	DUMP(p, tm_scratch, "%#-*llx");
2430 #endif
2431 
2432 #ifdef CONFIG_PPC_POWERNV
2433 	DUMP(p, core_idle_state_ptr, "%-*px");
2434 	DUMP(p, thread_idle_state, "%#-*x");
2435 	DUMP(p, thread_mask, "%#-*x");
2436 	DUMP(p, subcore_sibling_mask, "%#-*x");
2437 	DUMP(p, requested_psscr, "%#-*llx");
2438 	DUMP(p, stop_sprs.pid, "%#-*llx");
2439 	DUMP(p, stop_sprs.ldbar, "%#-*llx");
2440 	DUMP(p, stop_sprs.fscr, "%#-*llx");
2441 	DUMP(p, stop_sprs.hfscr, "%#-*llx");
2442 	DUMP(p, stop_sprs.mmcr1, "%#-*llx");
2443 	DUMP(p, stop_sprs.mmcr2, "%#-*llx");
2444 	DUMP(p, stop_sprs.mmcra, "%#-*llx");
2445 	DUMP(p, dont_stop.counter, "%#-*x");
2446 #endif
2447 
2448 	DUMP(p, accounting.utime, "%#-*lx");
2449 	DUMP(p, accounting.stime, "%#-*lx");
2450 	DUMP(p, accounting.utime_scaled, "%#-*lx");
2451 	DUMP(p, accounting.starttime, "%#-*lx");
2452 	DUMP(p, accounting.starttime_user, "%#-*lx");
2453 	DUMP(p, accounting.startspurr, "%#-*lx");
2454 	DUMP(p, accounting.utime_sspurr, "%#-*lx");
2455 	DUMP(p, accounting.steal_time, "%#-*lx");
2456 #undef DUMP
2457 
2458 	catch_memory_errors = 0;
2459 	sync();
2460 }
2461 
dump_all_pacas(void)2462 static void dump_all_pacas(void)
2463 {
2464 	int cpu;
2465 
2466 	if (num_possible_cpus() == 0) {
2467 		printf("No possible cpus, use 'dp #' to dump individual cpus\n");
2468 		return;
2469 	}
2470 
2471 	for_each_possible_cpu(cpu)
2472 		dump_one_paca(cpu);
2473 }
2474 
dump_pacas(void)2475 static void dump_pacas(void)
2476 {
2477 	unsigned long num;
2478 	int c;
2479 
2480 	c = inchar();
2481 	if (c == 'a') {
2482 		dump_all_pacas();
2483 		return;
2484 	}
2485 
2486 	termch = c;	/* Put c back, it wasn't 'a' */
2487 
2488 	if (scanhex(&num))
2489 		dump_one_paca(num);
2490 	else
2491 		dump_one_paca(xmon_owner);
2492 }
2493 #endif
2494 
2495 #ifdef CONFIG_PPC_POWERNV
dump_one_xive(int cpu)2496 static void dump_one_xive(int cpu)
2497 {
2498 	unsigned int hwid = get_hard_smp_processor_id(cpu);
2499 	bool hv = cpu_has_feature(CPU_FTR_HVMODE);
2500 
2501 	if (hv) {
2502 		opal_xive_dump(XIVE_DUMP_TM_HYP, hwid);
2503 		opal_xive_dump(XIVE_DUMP_TM_POOL, hwid);
2504 		opal_xive_dump(XIVE_DUMP_TM_OS, hwid);
2505 		opal_xive_dump(XIVE_DUMP_TM_USER, hwid);
2506 		opal_xive_dump(XIVE_DUMP_VP, hwid);
2507 		opal_xive_dump(XIVE_DUMP_EMU_STATE, hwid);
2508 	}
2509 
2510 	if (setjmp(bus_error_jmp) != 0) {
2511 		catch_memory_errors = 0;
2512 		printf("*** Error dumping xive on cpu %d\n", cpu);
2513 		return;
2514 	}
2515 
2516 	catch_memory_errors = 1;
2517 	sync();
2518 	xmon_xive_do_dump(cpu);
2519 	sync();
2520 	__delay(200);
2521 	catch_memory_errors = 0;
2522 }
2523 
dump_all_xives(void)2524 static void dump_all_xives(void)
2525 {
2526 	int cpu;
2527 
2528 	if (num_possible_cpus() == 0) {
2529 		printf("No possible cpus, use 'dx #' to dump individual cpus\n");
2530 		return;
2531 	}
2532 
2533 	for_each_possible_cpu(cpu)
2534 		dump_one_xive(cpu);
2535 }
2536 
dump_one_xive_irq(u32 num)2537 static void dump_one_xive_irq(u32 num)
2538 {
2539 	s64 rc;
2540 	__be64 vp;
2541 	u8 prio;
2542 	__be32 lirq;
2543 
2544 	rc = opal_xive_get_irq_config(num, &vp, &prio, &lirq);
2545 	xmon_printf("IRQ 0x%x config: vp=0x%llx prio=%d lirq=0x%x (rc=%lld)\n",
2546 		    num, be64_to_cpu(vp), prio, be32_to_cpu(lirq), rc);
2547 }
2548 
dump_xives(void)2549 static void dump_xives(void)
2550 {
2551 	unsigned long num;
2552 	int c;
2553 
2554 	if (!xive_enabled()) {
2555 		printf("Xive disabled on this system\n");
2556 		return;
2557 	}
2558 
2559 	c = inchar();
2560 	if (c == 'a') {
2561 		dump_all_xives();
2562 		return;
2563 	} else if (c == 'i') {
2564 		if (scanhex(&num))
2565 			dump_one_xive_irq(num);
2566 		return;
2567 	}
2568 
2569 	termch = c;	/* Put c back, it wasn't 'a' */
2570 
2571 	if (scanhex(&num))
2572 		dump_one_xive(num);
2573 	else
2574 		dump_one_xive(xmon_owner);
2575 }
2576 #endif /* CONFIG_PPC_POWERNV */
2577 
dump_by_size(unsigned long addr,long count,int size)2578 static void dump_by_size(unsigned long addr, long count, int size)
2579 {
2580 	unsigned char temp[16];
2581 	int i, j;
2582 	u64 val;
2583 
2584 	count = ALIGN(count, 16);
2585 
2586 	for (i = 0; i < count; i += 16, addr += 16) {
2587 		printf(REG, addr);
2588 
2589 		if (mread(addr, temp, 16) != 16) {
2590 			printf("\nFaulted reading %d bytes from 0x"REG"\n", 16, addr);
2591 			return;
2592 		}
2593 
2594 		for (j = 0; j < 16; j += size) {
2595 			putchar(' ');
2596 			switch (size) {
2597 			case 1: val = temp[j]; break;
2598 			case 2: val = *(u16 *)&temp[j]; break;
2599 			case 4: val = *(u32 *)&temp[j]; break;
2600 			case 8: val = *(u64 *)&temp[j]; break;
2601 			default: val = 0;
2602 			}
2603 
2604 			printf("%0*llx", size * 2, val);
2605 		}
2606 		printf("\n");
2607 	}
2608 }
2609 
2610 static void
dump(void)2611 dump(void)
2612 {
2613 	static char last[] = { "d?\n" };
2614 	int c;
2615 
2616 	c = inchar();
2617 
2618 #ifdef CONFIG_PPC64
2619 	if (c == 'p') {
2620 		xmon_start_pagination();
2621 		dump_pacas();
2622 		xmon_end_pagination();
2623 		return;
2624 	}
2625 #endif
2626 #ifdef CONFIG_PPC_POWERNV
2627 	if (c == 'x') {
2628 		xmon_start_pagination();
2629 		dump_xives();
2630 		xmon_end_pagination();
2631 		return;
2632 	}
2633 #endif
2634 
2635 	if (c == 't') {
2636 		dump_tracing();
2637 		return;
2638 	}
2639 
2640 	if (c == '\n')
2641 		termch = c;
2642 
2643 	scanhex((void *)&adrs);
2644 	if (termch != '\n')
2645 		termch = 0;
2646 	if (c == 'i') {
2647 		scanhex(&nidump);
2648 		if (nidump == 0)
2649 			nidump = 16;
2650 		else if (nidump > MAX_DUMP)
2651 			nidump = MAX_DUMP;
2652 		adrs += ppc_inst_dump(adrs, nidump, 1);
2653 		last_cmd = "di\n";
2654 	} else if (c == 'l') {
2655 		dump_log_buf();
2656 	} else if (c == 'o') {
2657 		dump_opal_msglog();
2658 	} else if (c == 'v') {
2659 		/* dump virtual to physical translation */
2660 		show_pte(adrs);
2661 	} else if (c == 'r') {
2662 		scanhex(&ndump);
2663 		if (ndump == 0)
2664 			ndump = 64;
2665 		xmon_rawdump(adrs, ndump);
2666 		adrs += ndump;
2667 		last_cmd = "dr\n";
2668 	} else {
2669 		scanhex(&ndump);
2670 		if (ndump == 0)
2671 			ndump = 64;
2672 		else if (ndump > MAX_DUMP)
2673 			ndump = MAX_DUMP;
2674 
2675 		switch (c) {
2676 		case '8':
2677 		case '4':
2678 		case '2':
2679 		case '1':
2680 			ndump = ALIGN(ndump, 16);
2681 			dump_by_size(adrs, ndump, c - '0');
2682 			last[1] = c;
2683 			last_cmd = last;
2684 			break;
2685 		default:
2686 			prdump(adrs, ndump);
2687 			last_cmd = "d\n";
2688 		}
2689 
2690 		adrs += ndump;
2691 	}
2692 }
2693 
2694 static void
prdump(unsigned long adrs,long ndump)2695 prdump(unsigned long adrs, long ndump)
2696 {
2697 	long n, m, c, r, nr;
2698 	unsigned char temp[16];
2699 
2700 	for (n = ndump; n > 0;) {
2701 		printf(REG, adrs);
2702 		putchar(' ');
2703 		r = n < 16? n: 16;
2704 		nr = mread(adrs, temp, r);
2705 		adrs += nr;
2706 		for (m = 0; m < r; ++m) {
2707 			if ((m & (sizeof(long) - 1)) == 0 && m > 0)
2708 				putchar(' ');
2709 			if (m < nr)
2710 				printf("%.2x", temp[m]);
2711 			else
2712 				printf("%s", fault_chars[fault_type]);
2713 		}
2714 		for (; m < 16; ++m) {
2715 			if ((m & (sizeof(long) - 1)) == 0)
2716 				putchar(' ');
2717 			printf("  ");
2718 		}
2719 		printf("  |");
2720 		for (m = 0; m < r; ++m) {
2721 			if (m < nr) {
2722 				c = temp[m];
2723 				putchar(' ' <= c && c <= '~'? c: '.');
2724 			} else
2725 				putchar(' ');
2726 		}
2727 		n -= r;
2728 		for (; m < 16; ++m)
2729 			putchar(' ');
2730 		printf("|\n");
2731 		if (nr < r)
2732 			break;
2733 	}
2734 }
2735 
2736 typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr);
2737 
2738 static int
generic_inst_dump(unsigned long adr,long count,int praddr,instruction_dump_func dump_func)2739 generic_inst_dump(unsigned long adr, long count, int praddr,
2740 			instruction_dump_func dump_func)
2741 {
2742 	int nr, dotted;
2743 	unsigned long first_adr;
2744 	unsigned int inst, last_inst = 0;
2745 	unsigned char val[4];
2746 
2747 	dotted = 0;
2748 	for (first_adr = adr; count > 0; --count, adr += 4) {
2749 		nr = mread(adr, val, 4);
2750 		if (nr == 0) {
2751 			if (praddr) {
2752 				const char *x = fault_chars[fault_type];
2753 				printf(REG"  %s%s%s%s\n", adr, x, x, x, x);
2754 			}
2755 			break;
2756 		}
2757 		inst = GETWORD(val);
2758 		if (adr > first_adr && inst == last_inst) {
2759 			if (!dotted) {
2760 				printf(" ...\n");
2761 				dotted = 1;
2762 			}
2763 			continue;
2764 		}
2765 		dotted = 0;
2766 		last_inst = inst;
2767 		if (praddr)
2768 			printf(REG"  %.8x", adr, inst);
2769 		printf("\t");
2770 		dump_func(inst, adr);
2771 		printf("\n");
2772 	}
2773 	return adr - first_adr;
2774 }
2775 
2776 static int
ppc_inst_dump(unsigned long adr,long count,int praddr)2777 ppc_inst_dump(unsigned long adr, long count, int praddr)
2778 {
2779 	return generic_inst_dump(adr, count, praddr, print_insn_powerpc);
2780 }
2781 
2782 void
print_address(unsigned long addr)2783 print_address(unsigned long addr)
2784 {
2785 	xmon_print_symbol(addr, "\t# ", "");
2786 }
2787 
2788 void
dump_log_buf(void)2789 dump_log_buf(void)
2790 {
2791 	struct kmsg_dumper dumper = { .active = 1 };
2792 	unsigned char buf[128];
2793 	size_t len;
2794 
2795 	if (setjmp(bus_error_jmp) != 0) {
2796 		printf("Error dumping printk buffer!\n");
2797 		return;
2798 	}
2799 
2800 	catch_memory_errors = 1;
2801 	sync();
2802 
2803 	kmsg_dump_rewind_nolock(&dumper);
2804 	xmon_start_pagination();
2805 	while (kmsg_dump_get_line_nolock(&dumper, false, buf, sizeof(buf), &len)) {
2806 		buf[len] = '\0';
2807 		printf("%s", buf);
2808 	}
2809 	xmon_end_pagination();
2810 
2811 	sync();
2812 	/* wait a little while to see if we get a machine check */
2813 	__delay(200);
2814 	catch_memory_errors = 0;
2815 }
2816 
2817 #ifdef CONFIG_PPC_POWERNV
dump_opal_msglog(void)2818 static void dump_opal_msglog(void)
2819 {
2820 	unsigned char buf[128];
2821 	ssize_t res;
2822 	loff_t pos = 0;
2823 
2824 	if (!firmware_has_feature(FW_FEATURE_OPAL)) {
2825 		printf("Machine is not running OPAL firmware.\n");
2826 		return;
2827 	}
2828 
2829 	if (setjmp(bus_error_jmp) != 0) {
2830 		printf("Error dumping OPAL msglog!\n");
2831 		return;
2832 	}
2833 
2834 	catch_memory_errors = 1;
2835 	sync();
2836 
2837 	xmon_start_pagination();
2838 	while ((res = opal_msglog_copy(buf, pos, sizeof(buf) - 1))) {
2839 		if (res < 0) {
2840 			printf("Error dumping OPAL msglog! Error: %zd\n", res);
2841 			break;
2842 		}
2843 		buf[res] = '\0';
2844 		printf("%s", buf);
2845 		pos += res;
2846 	}
2847 	xmon_end_pagination();
2848 
2849 	sync();
2850 	/* wait a little while to see if we get a machine check */
2851 	__delay(200);
2852 	catch_memory_errors = 0;
2853 }
2854 #endif
2855 
2856 /*
2857  * Memory operations - move, set, print differences
2858  */
2859 static unsigned long mdest;		/* destination address */
2860 static unsigned long msrc;		/* source address */
2861 static unsigned long mval;		/* byte value to set memory to */
2862 static unsigned long mcount;		/* # bytes to affect */
2863 static unsigned long mdiffs;		/* max # differences to print */
2864 
2865 static void
memops(int cmd)2866 memops(int cmd)
2867 {
2868 	scanhex((void *)&mdest);
2869 	if( termch != '\n' )
2870 		termch = 0;
2871 	scanhex((void *)(cmd == 's'? &mval: &msrc));
2872 	if( termch != '\n' )
2873 		termch = 0;
2874 	scanhex((void *)&mcount);
2875 	switch( cmd ){
2876 	case 'm':
2877 		memmove((void *)mdest, (void *)msrc, mcount);
2878 		break;
2879 	case 's':
2880 		memset((void *)mdest, mval, mcount);
2881 		break;
2882 	case 'd':
2883 		if( termch != '\n' )
2884 			termch = 0;
2885 		scanhex((void *)&mdiffs);
2886 		memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2887 		break;
2888 	}
2889 }
2890 
2891 static void
memdiffs(unsigned char * p1,unsigned char * p2,unsigned nb,unsigned maxpr)2892 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2893 {
2894 	unsigned n, prt;
2895 
2896 	prt = 0;
2897 	for( n = nb; n > 0; --n )
2898 		if( *p1++ != *p2++ )
2899 			if( ++prt <= maxpr )
2900 				printf("%px %.2x # %px %.2x\n", p1 - 1,
2901 					p1[-1], p2 - 1, p2[-1]);
2902 	if( prt > maxpr )
2903 		printf("Total of %d differences\n", prt);
2904 }
2905 
2906 static unsigned mend;
2907 static unsigned mask;
2908 
2909 static void
memlocate(void)2910 memlocate(void)
2911 {
2912 	unsigned a, n;
2913 	unsigned char val[4];
2914 
2915 	last_cmd = "ml";
2916 	scanhex((void *)&mdest);
2917 	if (termch != '\n') {
2918 		termch = 0;
2919 		scanhex((void *)&mend);
2920 		if (termch != '\n') {
2921 			termch = 0;
2922 			scanhex((void *)&mval);
2923 			mask = ~0;
2924 			if (termch != '\n') termch = 0;
2925 			scanhex((void *)&mask);
2926 		}
2927 	}
2928 	n = 0;
2929 	for (a = mdest; a < mend; a += 4) {
2930 		if (mread(a, val, 4) == 4
2931 			&& ((GETWORD(val) ^ mval) & mask) == 0) {
2932 			printf("%.16x:  %.16x\n", a, GETWORD(val));
2933 			if (++n >= 10)
2934 				break;
2935 		}
2936 	}
2937 }
2938 
2939 static unsigned long mskip = 0x1000;
2940 static unsigned long mlim = 0xffffffff;
2941 
2942 static void
memzcan(void)2943 memzcan(void)
2944 {
2945 	unsigned char v;
2946 	unsigned a;
2947 	int ok, ook;
2948 
2949 	scanhex(&mdest);
2950 	if (termch != '\n') termch = 0;
2951 	scanhex(&mskip);
2952 	if (termch != '\n') termch = 0;
2953 	scanhex(&mlim);
2954 	ook = 0;
2955 	for (a = mdest; a < mlim; a += mskip) {
2956 		ok = mread(a, &v, 1);
2957 		if (ok && !ook) {
2958 			printf("%.8x .. ", a);
2959 		} else if (!ok && ook)
2960 			printf("%.8lx\n", a - mskip);
2961 		ook = ok;
2962 		if (a + mskip < a)
2963 			break;
2964 	}
2965 	if (ook)
2966 		printf("%.8lx\n", a - mskip);
2967 }
2968 
show_task(struct task_struct * tsk)2969 static void show_task(struct task_struct *tsk)
2970 {
2971 	char state;
2972 
2973 	/*
2974 	 * Cloned from kdb_task_state_char(), which is not entirely
2975 	 * appropriate for calling from xmon. This could be moved
2976 	 * to a common, generic, routine used by both.
2977 	 */
2978 	state = (tsk->state == 0) ? 'R' :
2979 		(tsk->state < 0) ? 'U' :
2980 		(tsk->state & TASK_UNINTERRUPTIBLE) ? 'D' :
2981 		(tsk->state & TASK_STOPPED) ? 'T' :
2982 		(tsk->state & TASK_TRACED) ? 'C' :
2983 		(tsk->exit_state & EXIT_ZOMBIE) ? 'Z' :
2984 		(tsk->exit_state & EXIT_DEAD) ? 'E' :
2985 		(tsk->state & TASK_INTERRUPTIBLE) ? 'S' : '?';
2986 
2987 	printf("%px %016lx %6d %6d %c %2d %s\n", tsk,
2988 		tsk->thread.ksp,
2989 		tsk->pid, tsk->parent->pid,
2990 		state, task_thread_info(tsk)->cpu,
2991 		tsk->comm);
2992 }
2993 
2994 #ifdef CONFIG_PPC_BOOK3S_64
format_pte(void * ptep,unsigned long pte)2995 void format_pte(void *ptep, unsigned long pte)
2996 {
2997 	printf("ptep @ 0x%016lx = 0x%016lx\n", (unsigned long)ptep, pte);
2998 	printf("Maps physical address = 0x%016lx\n", pte & PTE_RPN_MASK);
2999 
3000 	printf("Flags = %s%s%s%s%s\n",
3001 	       (pte & _PAGE_ACCESSED) ? "Accessed " : "",
3002 	       (pte & _PAGE_DIRTY)    ? "Dirty " : "",
3003 	       (pte & _PAGE_READ)     ? "Read " : "",
3004 	       (pte & _PAGE_WRITE)    ? "Write " : "",
3005 	       (pte & _PAGE_EXEC)     ? "Exec " : "");
3006 }
3007 
show_pte(unsigned long addr)3008 static void show_pte(unsigned long addr)
3009 {
3010 	unsigned long tskv = 0;
3011 	struct task_struct *tsk = NULL;
3012 	struct mm_struct *mm;
3013 	pgd_t *pgdp, *pgdir;
3014 	pud_t *pudp;
3015 	pmd_t *pmdp;
3016 	pte_t *ptep;
3017 
3018 	if (!scanhex(&tskv))
3019 		mm = &init_mm;
3020 	else
3021 		tsk = (struct task_struct *)tskv;
3022 
3023 	if (tsk == NULL)
3024 		mm = &init_mm;
3025 	else
3026 		mm = tsk->active_mm;
3027 
3028 	if (setjmp(bus_error_jmp) != 0) {
3029 		catch_memory_errors = 0;
3030 		printf("*** Error dumping pte for task %px\n", tsk);
3031 		return;
3032 	}
3033 
3034 	catch_memory_errors = 1;
3035 	sync();
3036 
3037 	if (mm == &init_mm) {
3038 		pgdp = pgd_offset_k(addr);
3039 		pgdir = pgd_offset_k(0);
3040 	} else {
3041 		pgdp = pgd_offset(mm, addr);
3042 		pgdir = pgd_offset(mm, 0);
3043 	}
3044 
3045 	if (pgd_none(*pgdp)) {
3046 		printf("no linux page table for address\n");
3047 		return;
3048 	}
3049 
3050 	printf("pgd  @ 0x%px\n", pgdir);
3051 
3052 	if (pgd_huge(*pgdp)) {
3053 		format_pte(pgdp, pgd_val(*pgdp));
3054 		return;
3055 	}
3056 	printf("pgdp @ 0x%px = 0x%016lx\n", pgdp, pgd_val(*pgdp));
3057 
3058 	pudp = pud_offset(pgdp, addr);
3059 
3060 	if (pud_none(*pudp)) {
3061 		printf("No valid PUD\n");
3062 		return;
3063 	}
3064 
3065 	if (pud_huge(*pudp)) {
3066 		format_pte(pudp, pud_val(*pudp));
3067 		return;
3068 	}
3069 
3070 	printf("pudp @ 0x%px = 0x%016lx\n", pudp, pud_val(*pudp));
3071 
3072 	pmdp = pmd_offset(pudp, addr);
3073 
3074 	if (pmd_none(*pmdp)) {
3075 		printf("No valid PMD\n");
3076 		return;
3077 	}
3078 
3079 	if (pmd_huge(*pmdp)) {
3080 		format_pte(pmdp, pmd_val(*pmdp));
3081 		return;
3082 	}
3083 	printf("pmdp @ 0x%px = 0x%016lx\n", pmdp, pmd_val(*pmdp));
3084 
3085 	ptep = pte_offset_map(pmdp, addr);
3086 	if (pte_none(*ptep)) {
3087 		printf("no valid PTE\n");
3088 		return;
3089 	}
3090 
3091 	format_pte(ptep, pte_val(*ptep));
3092 
3093 	sync();
3094 	__delay(200);
3095 	catch_memory_errors = 0;
3096 }
3097 #else
show_pte(unsigned long addr)3098 static void show_pte(unsigned long addr)
3099 {
3100 	printf("show_pte not yet implemented\n");
3101 }
3102 #endif /* CONFIG_PPC_BOOK3S_64 */
3103 
show_tasks(void)3104 static void show_tasks(void)
3105 {
3106 	unsigned long tskv;
3107 	struct task_struct *tsk = NULL;
3108 
3109 	printf("     task_struct     ->thread.ksp    PID   PPID S  P CMD\n");
3110 
3111 	if (scanhex(&tskv))
3112 		tsk = (struct task_struct *)tskv;
3113 
3114 	if (setjmp(bus_error_jmp) != 0) {
3115 		catch_memory_errors = 0;
3116 		printf("*** Error dumping task %px\n", tsk);
3117 		return;
3118 	}
3119 
3120 	catch_memory_errors = 1;
3121 	sync();
3122 
3123 	if (tsk)
3124 		show_task(tsk);
3125 	else
3126 		for_each_process(tsk)
3127 			show_task(tsk);
3128 
3129 	sync();
3130 	__delay(200);
3131 	catch_memory_errors = 0;
3132 }
3133 
proccall(void)3134 static void proccall(void)
3135 {
3136 	unsigned long args[8];
3137 	unsigned long ret;
3138 	int i;
3139 	typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
3140 			unsigned long, unsigned long, unsigned long,
3141 			unsigned long, unsigned long, unsigned long);
3142 	callfunc_t func;
3143 
3144 	if (!scanhex(&adrs))
3145 		return;
3146 	if (termch != '\n')
3147 		termch = 0;
3148 	for (i = 0; i < 8; ++i)
3149 		args[i] = 0;
3150 	for (i = 0; i < 8; ++i) {
3151 		if (!scanhex(&args[i]) || termch == '\n')
3152 			break;
3153 		termch = 0;
3154 	}
3155 	func = (callfunc_t) adrs;
3156 	ret = 0;
3157 	if (setjmp(bus_error_jmp) == 0) {
3158 		catch_memory_errors = 1;
3159 		sync();
3160 		ret = func(args[0], args[1], args[2], args[3],
3161 			   args[4], args[5], args[6], args[7]);
3162 		sync();
3163 		printf("return value is 0x%lx\n", ret);
3164 	} else {
3165 		printf("*** %x exception occurred\n", fault_except);
3166 	}
3167 	catch_memory_errors = 0;
3168 }
3169 
3170 /* Input scanning routines */
3171 int
skipbl(void)3172 skipbl(void)
3173 {
3174 	int c;
3175 
3176 	if( termch != 0 ){
3177 		c = termch;
3178 		termch = 0;
3179 	} else
3180 		c = inchar();
3181 	while( c == ' ' || c == '\t' )
3182 		c = inchar();
3183 	return c;
3184 }
3185 
3186 #define N_PTREGS	44
3187 static const char *regnames[N_PTREGS] = {
3188 	"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
3189 	"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
3190 	"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
3191 	"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
3192 	"pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
3193 #ifdef CONFIG_PPC64
3194 	"softe",
3195 #else
3196 	"mq",
3197 #endif
3198 	"trap", "dar", "dsisr", "res"
3199 };
3200 
3201 int
scanhex(unsigned long * vp)3202 scanhex(unsigned long *vp)
3203 {
3204 	int c, d;
3205 	unsigned long v;
3206 
3207 	c = skipbl();
3208 	if (c == '%') {
3209 		/* parse register name */
3210 		char regname[8];
3211 		int i;
3212 
3213 		for (i = 0; i < sizeof(regname) - 1; ++i) {
3214 			c = inchar();
3215 			if (!isalnum(c)) {
3216 				termch = c;
3217 				break;
3218 			}
3219 			regname[i] = c;
3220 		}
3221 		regname[i] = 0;
3222 		i = match_string(regnames, N_PTREGS, regname);
3223 		if (i < 0) {
3224 			printf("invalid register name '%%%s'\n", regname);
3225 			return 0;
3226 		}
3227 		if (xmon_regs == NULL) {
3228 			printf("regs not available\n");
3229 			return 0;
3230 		}
3231 		*vp = ((unsigned long *)xmon_regs)[i];
3232 		return 1;
3233 	}
3234 
3235 	/* skip leading "0x" if any */
3236 
3237 	if (c == '0') {
3238 		c = inchar();
3239 		if (c == 'x') {
3240 			c = inchar();
3241 		} else {
3242 			d = hexdigit(c);
3243 			if (d == EOF) {
3244 				termch = c;
3245 				*vp = 0;
3246 				return 1;
3247 			}
3248 		}
3249 	} else if (c == '$') {
3250 		int i;
3251 		for (i=0; i<63; i++) {
3252 			c = inchar();
3253 			if (isspace(c) || c == '\0') {
3254 				termch = c;
3255 				break;
3256 			}
3257 			tmpstr[i] = c;
3258 		}
3259 		tmpstr[i++] = 0;
3260 		*vp = 0;
3261 		if (setjmp(bus_error_jmp) == 0) {
3262 			catch_memory_errors = 1;
3263 			sync();
3264 			*vp = kallsyms_lookup_name(tmpstr);
3265 			sync();
3266 		}
3267 		catch_memory_errors = 0;
3268 		if (!(*vp)) {
3269 			printf("unknown symbol '%s'\n", tmpstr);
3270 			return 0;
3271 		}
3272 		return 1;
3273 	}
3274 
3275 	d = hexdigit(c);
3276 	if (d == EOF) {
3277 		termch = c;
3278 		return 0;
3279 	}
3280 	v = 0;
3281 	do {
3282 		v = (v << 4) + d;
3283 		c = inchar();
3284 		d = hexdigit(c);
3285 	} while (d != EOF);
3286 	termch = c;
3287 	*vp = v;
3288 	return 1;
3289 }
3290 
3291 static void
scannl(void)3292 scannl(void)
3293 {
3294 	int c;
3295 
3296 	c = termch;
3297 	termch = 0;
3298 	while( c != '\n' )
3299 		c = inchar();
3300 }
3301 
hexdigit(int c)3302 static int hexdigit(int c)
3303 {
3304 	if( '0' <= c && c <= '9' )
3305 		return c - '0';
3306 	if( 'A' <= c && c <= 'F' )
3307 		return c - ('A' - 10);
3308 	if( 'a' <= c && c <= 'f' )
3309 		return c - ('a' - 10);
3310 	return EOF;
3311 }
3312 
3313 void
getstring(char * s,int size)3314 getstring(char *s, int size)
3315 {
3316 	int c;
3317 
3318 	c = skipbl();
3319 	do {
3320 		if( size > 1 ){
3321 			*s++ = c;
3322 			--size;
3323 		}
3324 		c = inchar();
3325 	} while( c != ' ' && c != '\t' && c != '\n' );
3326 	termch = c;
3327 	*s = 0;
3328 }
3329 
3330 static char line[256];
3331 static char *lineptr;
3332 
3333 static void
flush_input(void)3334 flush_input(void)
3335 {
3336 	lineptr = NULL;
3337 }
3338 
3339 static int
inchar(void)3340 inchar(void)
3341 {
3342 	if (lineptr == NULL || *lineptr == 0) {
3343 		if (xmon_gets(line, sizeof(line)) == NULL) {
3344 			lineptr = NULL;
3345 			return EOF;
3346 		}
3347 		lineptr = line;
3348 	}
3349 	return *lineptr++;
3350 }
3351 
3352 static void
take_input(char * str)3353 take_input(char *str)
3354 {
3355 	lineptr = str;
3356 }
3357 
3358 
3359 static void
symbol_lookup(void)3360 symbol_lookup(void)
3361 {
3362 	int type = inchar();
3363 	unsigned long addr, cpu;
3364 	void __percpu *ptr = NULL;
3365 	static char tmp[64];
3366 
3367 	switch (type) {
3368 	case 'a':
3369 		if (scanhex(&addr))
3370 			xmon_print_symbol(addr, ": ", "\n");
3371 		termch = 0;
3372 		break;
3373 	case 's':
3374 		getstring(tmp, 64);
3375 		if (setjmp(bus_error_jmp) == 0) {
3376 			catch_memory_errors = 1;
3377 			sync();
3378 			addr = kallsyms_lookup_name(tmp);
3379 			if (addr)
3380 				printf("%s: %lx\n", tmp, addr);
3381 			else
3382 				printf("Symbol '%s' not found.\n", tmp);
3383 			sync();
3384 		}
3385 		catch_memory_errors = 0;
3386 		termch = 0;
3387 		break;
3388 	case 'p':
3389 		getstring(tmp, 64);
3390 		if (setjmp(bus_error_jmp) == 0) {
3391 			catch_memory_errors = 1;
3392 			sync();
3393 			ptr = (void __percpu *)kallsyms_lookup_name(tmp);
3394 			sync();
3395 		}
3396 
3397 		if (ptr &&
3398 		    ptr >= (void __percpu *)__per_cpu_start &&
3399 		    ptr < (void __percpu *)__per_cpu_end)
3400 		{
3401 			if (scanhex(&cpu) && cpu < num_possible_cpus()) {
3402 				addr = (unsigned long)per_cpu_ptr(ptr, cpu);
3403 			} else {
3404 				cpu = raw_smp_processor_id();
3405 				addr = (unsigned long)this_cpu_ptr(ptr);
3406 			}
3407 
3408 			printf("%s for cpu 0x%lx: %lx\n", tmp, cpu, addr);
3409 		} else {
3410 			printf("Percpu symbol '%s' not found.\n", tmp);
3411 		}
3412 
3413 		catch_memory_errors = 0;
3414 		termch = 0;
3415 		break;
3416 	}
3417 }
3418 
3419 
3420 /* Print an address in numeric and symbolic form (if possible) */
xmon_print_symbol(unsigned long address,const char * mid,const char * after)3421 static void xmon_print_symbol(unsigned long address, const char *mid,
3422 			      const char *after)
3423 {
3424 	char *modname;
3425 	const char *name = NULL;
3426 	unsigned long offset, size;
3427 
3428 	printf(REG, address);
3429 	if (setjmp(bus_error_jmp) == 0) {
3430 		catch_memory_errors = 1;
3431 		sync();
3432 		name = kallsyms_lookup(address, &size, &offset, &modname,
3433 				       tmpstr);
3434 		sync();
3435 		/* wait a little while to see if we get a machine check */
3436 		__delay(200);
3437 	}
3438 
3439 	catch_memory_errors = 0;
3440 
3441 	if (name) {
3442 		printf("%s%s+%#lx/%#lx", mid, name, offset, size);
3443 		if (modname)
3444 			printf(" [%s]", modname);
3445 	}
3446 	printf("%s", after);
3447 }
3448 
3449 #ifdef CONFIG_PPC_BOOK3S_64
dump_segments(void)3450 void dump_segments(void)
3451 {
3452 	int i;
3453 	unsigned long esid,vsid;
3454 	unsigned long llp;
3455 
3456 	printf("SLB contents of cpu 0x%x\n", smp_processor_id());
3457 
3458 	for (i = 0; i < mmu_slb_size; i++) {
3459 		asm volatile("slbmfee  %0,%1" : "=r" (esid) : "r" (i));
3460 		asm volatile("slbmfev  %0,%1" : "=r" (vsid) : "r" (i));
3461 
3462 		if (!esid && !vsid)
3463 			continue;
3464 
3465 		printf("%02d %016lx %016lx", i, esid, vsid);
3466 
3467 		if (!(esid & SLB_ESID_V)) {
3468 			printf("\n");
3469 			continue;
3470 		}
3471 
3472 		llp = vsid & SLB_VSID_LLP;
3473 		if (vsid & SLB_VSID_B_1T) {
3474 			printf("  1T  ESID=%9lx  VSID=%13lx LLP:%3lx \n",
3475 				GET_ESID_1T(esid),
3476 				(vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T,
3477 				llp);
3478 		} else {
3479 			printf(" 256M ESID=%9lx  VSID=%13lx LLP:%3lx \n",
3480 				GET_ESID(esid),
3481 				(vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT,
3482 				llp);
3483 		}
3484 	}
3485 }
3486 #endif
3487 
3488 #ifdef CONFIG_PPC_STD_MMU_32
dump_segments(void)3489 void dump_segments(void)
3490 {
3491 	int i;
3492 
3493 	printf("sr0-15 =");
3494 	for (i = 0; i < 16; ++i)
3495 		printf(" %x", mfsrin(i << 28));
3496 	printf("\n");
3497 }
3498 #endif
3499 
3500 #ifdef CONFIG_44x
dump_tlb_44x(void)3501 static void dump_tlb_44x(void)
3502 {
3503 	int i;
3504 
3505 	for (i = 0; i < PPC44x_TLB_SIZE; i++) {
3506 		unsigned long w0,w1,w2;
3507 		asm volatile("tlbre  %0,%1,0" : "=r" (w0) : "r" (i));
3508 		asm volatile("tlbre  %0,%1,1" : "=r" (w1) : "r" (i));
3509 		asm volatile("tlbre  %0,%1,2" : "=r" (w2) : "r" (i));
3510 		printf("[%02x] %08lx %08lx %08lx ", i, w0, w1, w2);
3511 		if (w0 & PPC44x_TLB_VALID) {
3512 			printf("V %08lx -> %01lx%08lx %c%c%c%c%c",
3513 			       w0 & PPC44x_TLB_EPN_MASK,
3514 			       w1 & PPC44x_TLB_ERPN_MASK,
3515 			       w1 & PPC44x_TLB_RPN_MASK,
3516 			       (w2 & PPC44x_TLB_W) ? 'W' : 'w',
3517 			       (w2 & PPC44x_TLB_I) ? 'I' : 'i',
3518 			       (w2 & PPC44x_TLB_M) ? 'M' : 'm',
3519 			       (w2 & PPC44x_TLB_G) ? 'G' : 'g',
3520 			       (w2 & PPC44x_TLB_E) ? 'E' : 'e');
3521 		}
3522 		printf("\n");
3523 	}
3524 }
3525 #endif /* CONFIG_44x */
3526 
3527 #ifdef CONFIG_PPC_BOOK3E
dump_tlb_book3e(void)3528 static void dump_tlb_book3e(void)
3529 {
3530 	u32 mmucfg, pidmask, lpidmask;
3531 	u64 ramask;
3532 	int i, tlb, ntlbs, pidsz, lpidsz, rasz, lrat = 0;
3533 	int mmu_version;
3534 	static const char *pgsz_names[] = {
3535 		"  1K",
3536 		"  2K",
3537 		"  4K",
3538 		"  8K",
3539 		" 16K",
3540 		" 32K",
3541 		" 64K",
3542 		"128K",
3543 		"256K",
3544 		"512K",
3545 		"  1M",
3546 		"  2M",
3547 		"  4M",
3548 		"  8M",
3549 		" 16M",
3550 		" 32M",
3551 		" 64M",
3552 		"128M",
3553 		"256M",
3554 		"512M",
3555 		"  1G",
3556 		"  2G",
3557 		"  4G",
3558 		"  8G",
3559 		" 16G",
3560 		" 32G",
3561 		" 64G",
3562 		"128G",
3563 		"256G",
3564 		"512G",
3565 		"  1T",
3566 		"  2T",
3567 	};
3568 
3569 	/* Gather some infos about the MMU */
3570 	mmucfg = mfspr(SPRN_MMUCFG);
3571 	mmu_version = (mmucfg & 3) + 1;
3572 	ntlbs = ((mmucfg >> 2) & 3) + 1;
3573 	pidsz = ((mmucfg >> 6) & 0x1f) + 1;
3574 	lpidsz = (mmucfg >> 24) & 0xf;
3575 	rasz = (mmucfg >> 16) & 0x7f;
3576 	if ((mmu_version > 1) && (mmucfg & 0x10000))
3577 		lrat = 1;
3578 	printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n",
3579 	       mmu_version, ntlbs, pidsz, lpidsz, rasz);
3580 	pidmask = (1ul << pidsz) - 1;
3581 	lpidmask = (1ul << lpidsz) - 1;
3582 	ramask = (1ull << rasz) - 1;
3583 
3584 	for (tlb = 0; tlb < ntlbs; tlb++) {
3585 		u32 tlbcfg;
3586 		int nent, assoc, new_cc = 1;
3587 		printf("TLB %d:\n------\n", tlb);
3588 		switch(tlb) {
3589 		case 0:
3590 			tlbcfg = mfspr(SPRN_TLB0CFG);
3591 			break;
3592 		case 1:
3593 			tlbcfg = mfspr(SPRN_TLB1CFG);
3594 			break;
3595 		case 2:
3596 			tlbcfg = mfspr(SPRN_TLB2CFG);
3597 			break;
3598 		case 3:
3599 			tlbcfg = mfspr(SPRN_TLB3CFG);
3600 			break;
3601 		default:
3602 			printf("Unsupported TLB number !\n");
3603 			continue;
3604 		}
3605 		nent = tlbcfg & 0xfff;
3606 		assoc = (tlbcfg >> 24) & 0xff;
3607 		for (i = 0; i < nent; i++) {
3608 			u32 mas0 = MAS0_TLBSEL(tlb);
3609 			u32 mas1 = MAS1_TSIZE(BOOK3E_PAGESZ_4K);
3610 			u64 mas2 = 0;
3611 			u64 mas7_mas3;
3612 			int esel = i, cc = i;
3613 
3614 			if (assoc != 0) {
3615 				cc = i / assoc;
3616 				esel = i % assoc;
3617 				mas2 = cc * 0x1000;
3618 			}
3619 
3620 			mas0 |= MAS0_ESEL(esel);
3621 			mtspr(SPRN_MAS0, mas0);
3622 			mtspr(SPRN_MAS1, mas1);
3623 			mtspr(SPRN_MAS2, mas2);
3624 			asm volatile("tlbre  0,0,0" : : : "memory");
3625 			mas1 = mfspr(SPRN_MAS1);
3626 			mas2 = mfspr(SPRN_MAS2);
3627 			mas7_mas3 = mfspr(SPRN_MAS7_MAS3);
3628 			if (assoc && (i % assoc) == 0)
3629 				new_cc = 1;
3630 			if (!(mas1 & MAS1_VALID))
3631 				continue;
3632 			if (assoc == 0)
3633 				printf("%04x- ", i);
3634 			else if (new_cc)
3635 				printf("%04x-%c", cc, 'A' + esel);
3636 			else
3637 				printf("    |%c", 'A' + esel);
3638 			new_cc = 0;
3639 			printf(" %016llx %04x %s %c%c AS%c",
3640 			       mas2 & ~0x3ffull,
3641 			       (mas1 >> 16) & 0x3fff,
3642 			       pgsz_names[(mas1 >> 7) & 0x1f],
3643 			       mas1 & MAS1_IND ? 'I' : ' ',
3644 			       mas1 & MAS1_IPROT ? 'P' : ' ',
3645 			       mas1 & MAS1_TS ? '1' : '0');
3646 			printf(" %c%c%c%c%c%c%c",
3647 			       mas2 & MAS2_X0 ? 'a' : ' ',
3648 			       mas2 & MAS2_X1 ? 'v' : ' ',
3649 			       mas2 & MAS2_W  ? 'w' : ' ',
3650 			       mas2 & MAS2_I  ? 'i' : ' ',
3651 			       mas2 & MAS2_M  ? 'm' : ' ',
3652 			       mas2 & MAS2_G  ? 'g' : ' ',
3653 			       mas2 & MAS2_E  ? 'e' : ' ');
3654 			printf(" %016llx", mas7_mas3 & ramask & ~0x7ffull);
3655 			if (mas1 & MAS1_IND)
3656 				printf(" %s\n",
3657 				       pgsz_names[(mas7_mas3 >> 1) & 0x1f]);
3658 			else
3659 				printf(" U%c%c%c S%c%c%c\n",
3660 				       mas7_mas3 & MAS3_UX ? 'x' : ' ',
3661 				       mas7_mas3 & MAS3_UW ? 'w' : ' ',
3662 				       mas7_mas3 & MAS3_UR ? 'r' : ' ',
3663 				       mas7_mas3 & MAS3_SX ? 'x' : ' ',
3664 				       mas7_mas3 & MAS3_SW ? 'w' : ' ',
3665 				       mas7_mas3 & MAS3_SR ? 'r' : ' ');
3666 		}
3667 	}
3668 }
3669 #endif /* CONFIG_PPC_BOOK3E */
3670 
xmon_init(int enable)3671 static void xmon_init(int enable)
3672 {
3673 	if (enable) {
3674 		__debugger = xmon;
3675 		__debugger_ipi = xmon_ipi;
3676 		__debugger_bpt = xmon_bpt;
3677 		__debugger_sstep = xmon_sstep;
3678 		__debugger_iabr_match = xmon_iabr_match;
3679 		__debugger_break_match = xmon_break_match;
3680 		__debugger_fault_handler = xmon_fault_handler;
3681 
3682 #ifdef CONFIG_PPC_PSERIES
3683 		/*
3684 		 * Get the token here to avoid trying to get a lock
3685 		 * during the crash, causing a deadlock.
3686 		 */
3687 		set_indicator_token = rtas_token("set-indicator");
3688 #endif
3689 	} else {
3690 		__debugger = NULL;
3691 		__debugger_ipi = NULL;
3692 		__debugger_bpt = NULL;
3693 		__debugger_sstep = NULL;
3694 		__debugger_iabr_match = NULL;
3695 		__debugger_break_match = NULL;
3696 		__debugger_fault_handler = NULL;
3697 	}
3698 }
3699 
3700 #ifdef CONFIG_MAGIC_SYSRQ
sysrq_handle_xmon(int key)3701 static void sysrq_handle_xmon(int key)
3702 {
3703 	/* ensure xmon is enabled */
3704 	xmon_init(1);
3705 	debugger(get_irq_regs());
3706 	if (!xmon_on)
3707 		xmon_init(0);
3708 }
3709 
3710 static struct sysrq_key_op sysrq_xmon_op = {
3711 	.handler =	sysrq_handle_xmon,
3712 	.help_msg =	"xmon(x)",
3713 	.action_msg =	"Entering xmon",
3714 };
3715 
setup_xmon_sysrq(void)3716 static int __init setup_xmon_sysrq(void)
3717 {
3718 	register_sysrq_key('x', &sysrq_xmon_op);
3719 	return 0;
3720 }
3721 device_initcall(setup_xmon_sysrq);
3722 #endif /* CONFIG_MAGIC_SYSRQ */
3723 
3724 #ifdef CONFIG_DEBUG_FS
clear_all_bpt(void)3725 static void clear_all_bpt(void)
3726 {
3727 	int i;
3728 
3729 	/* clear/unpatch all breakpoints */
3730 	remove_bpts();
3731 	remove_cpu_bpts();
3732 
3733 	/* Disable all breakpoints */
3734 	for (i = 0; i < NBPTS; ++i)
3735 		bpts[i].enabled = 0;
3736 
3737 	/* Clear any data or iabr breakpoints */
3738 	if (iabr || dabr.enabled) {
3739 		iabr = NULL;
3740 		dabr.enabled = 0;
3741 	}
3742 
3743 	printf("xmon: All breakpoints cleared\n");
3744 }
3745 
xmon_dbgfs_set(void * data,u64 val)3746 static int xmon_dbgfs_set(void *data, u64 val)
3747 {
3748 	xmon_on = !!val;
3749 	xmon_init(xmon_on);
3750 
3751 	/* make sure all breakpoints removed when disabling */
3752 	if (!xmon_on)
3753 		clear_all_bpt();
3754 	return 0;
3755 }
3756 
xmon_dbgfs_get(void * data,u64 * val)3757 static int xmon_dbgfs_get(void *data, u64 *val)
3758 {
3759 	*val = xmon_on;
3760 	return 0;
3761 }
3762 
3763 DEFINE_SIMPLE_ATTRIBUTE(xmon_dbgfs_ops, xmon_dbgfs_get,
3764 			xmon_dbgfs_set, "%llu\n");
3765 
setup_xmon_dbgfs(void)3766 static int __init setup_xmon_dbgfs(void)
3767 {
3768 	debugfs_create_file("xmon", 0600, powerpc_debugfs_root, NULL,
3769 				&xmon_dbgfs_ops);
3770 	return 0;
3771 }
3772 device_initcall(setup_xmon_dbgfs);
3773 #endif /* CONFIG_DEBUG_FS */
3774 
3775 static int xmon_early __initdata;
3776 
early_parse_xmon(char * p)3777 static int __init early_parse_xmon(char *p)
3778 {
3779 	if (!p || strncmp(p, "early", 5) == 0) {
3780 		/* just "xmon" is equivalent to "xmon=early" */
3781 		xmon_init(1);
3782 		xmon_early = 1;
3783 		xmon_on = 1;
3784 	} else if (strncmp(p, "on", 2) == 0) {
3785 		xmon_init(1);
3786 		xmon_on = 1;
3787 	} else if (strncmp(p, "off", 3) == 0)
3788 		xmon_on = 0;
3789 	else
3790 		return 1;
3791 
3792 	return 0;
3793 }
3794 early_param("xmon", early_parse_xmon);
3795 
xmon_setup(void)3796 void __init xmon_setup(void)
3797 {
3798 	if (xmon_on)
3799 		xmon_init(1);
3800 	if (xmon_early)
3801 		debugger(NULL);
3802 }
3803 
3804 #ifdef CONFIG_SPU_BASE
3805 
3806 struct spu_info {
3807 	struct spu *spu;
3808 	u64 saved_mfc_sr1_RW;
3809 	u32 saved_spu_runcntl_RW;
3810 	unsigned long dump_addr;
3811 	u8 stopped_ok;
3812 };
3813 
3814 #define XMON_NUM_SPUS	16	/* Enough for current hardware */
3815 
3816 static struct spu_info spu_info[XMON_NUM_SPUS];
3817 
xmon_register_spus(struct list_head * list)3818 void xmon_register_spus(struct list_head *list)
3819 {
3820 	struct spu *spu;
3821 
3822 	list_for_each_entry(spu, list, full_list) {
3823 		if (spu->number >= XMON_NUM_SPUS) {
3824 			WARN_ON(1);
3825 			continue;
3826 		}
3827 
3828 		spu_info[spu->number].spu = spu;
3829 		spu_info[spu->number].stopped_ok = 0;
3830 		spu_info[spu->number].dump_addr = (unsigned long)
3831 				spu_info[spu->number].spu->local_store;
3832 	}
3833 }
3834 
stop_spus(void)3835 static void stop_spus(void)
3836 {
3837 	struct spu *spu;
3838 	int i;
3839 	u64 tmp;
3840 
3841 	for (i = 0; i < XMON_NUM_SPUS; i++) {
3842 		if (!spu_info[i].spu)
3843 			continue;
3844 
3845 		if (setjmp(bus_error_jmp) == 0) {
3846 			catch_memory_errors = 1;
3847 			sync();
3848 
3849 			spu = spu_info[i].spu;
3850 
3851 			spu_info[i].saved_spu_runcntl_RW =
3852 				in_be32(&spu->problem->spu_runcntl_RW);
3853 
3854 			tmp = spu_mfc_sr1_get(spu);
3855 			spu_info[i].saved_mfc_sr1_RW = tmp;
3856 
3857 			tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
3858 			spu_mfc_sr1_set(spu, tmp);
3859 
3860 			sync();
3861 			__delay(200);
3862 
3863 			spu_info[i].stopped_ok = 1;
3864 
3865 			printf("Stopped spu %.2d (was %s)\n", i,
3866 					spu_info[i].saved_spu_runcntl_RW ?
3867 					"running" : "stopped");
3868 		} else {
3869 			catch_memory_errors = 0;
3870 			printf("*** Error stopping spu %.2d\n", i);
3871 		}
3872 		catch_memory_errors = 0;
3873 	}
3874 }
3875 
restart_spus(void)3876 static void restart_spus(void)
3877 {
3878 	struct spu *spu;
3879 	int i;
3880 
3881 	for (i = 0; i < XMON_NUM_SPUS; i++) {
3882 		if (!spu_info[i].spu)
3883 			continue;
3884 
3885 		if (!spu_info[i].stopped_ok) {
3886 			printf("*** Error, spu %d was not successfully stopped"
3887 					", not restarting\n", i);
3888 			continue;
3889 		}
3890 
3891 		if (setjmp(bus_error_jmp) == 0) {
3892 			catch_memory_errors = 1;
3893 			sync();
3894 
3895 			spu = spu_info[i].spu;
3896 			spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
3897 			out_be32(&spu->problem->spu_runcntl_RW,
3898 					spu_info[i].saved_spu_runcntl_RW);
3899 
3900 			sync();
3901 			__delay(200);
3902 
3903 			printf("Restarted spu %.2d\n", i);
3904 		} else {
3905 			catch_memory_errors = 0;
3906 			printf("*** Error restarting spu %.2d\n", i);
3907 		}
3908 		catch_memory_errors = 0;
3909 	}
3910 }
3911 
3912 #define DUMP_WIDTH	23
3913 #define DUMP_VALUE(format, field, value)				\
3914 do {									\
3915 	if (setjmp(bus_error_jmp) == 0) {				\
3916 		catch_memory_errors = 1;				\
3917 		sync();							\
3918 		printf("  %-*s = "format"\n", DUMP_WIDTH,		\
3919 				#field, value);				\
3920 		sync();							\
3921 		__delay(200);						\
3922 	} else {							\
3923 		catch_memory_errors = 0;				\
3924 		printf("  %-*s = *** Error reading field.\n",		\
3925 					DUMP_WIDTH, #field);		\
3926 	}								\
3927 	catch_memory_errors = 0;					\
3928 } while (0)
3929 
3930 #define DUMP_FIELD(obj, format, field)	\
3931 	DUMP_VALUE(format, field, obj->field)
3932 
dump_spu_fields(struct spu * spu)3933 static void dump_spu_fields(struct spu *spu)
3934 {
3935 	printf("Dumping spu fields at address %p:\n", spu);
3936 
3937 	DUMP_FIELD(spu, "0x%x", number);
3938 	DUMP_FIELD(spu, "%s", name);
3939 	DUMP_FIELD(spu, "0x%lx", local_store_phys);
3940 	DUMP_FIELD(spu, "0x%p", local_store);
3941 	DUMP_FIELD(spu, "0x%lx", ls_size);
3942 	DUMP_FIELD(spu, "0x%x", node);
3943 	DUMP_FIELD(spu, "0x%lx", flags);
3944 	DUMP_FIELD(spu, "%llu", class_0_pending);
3945 	DUMP_FIELD(spu, "0x%llx", class_0_dar);
3946 	DUMP_FIELD(spu, "0x%llx", class_1_dar);
3947 	DUMP_FIELD(spu, "0x%llx", class_1_dsisr);
3948 	DUMP_FIELD(spu, "0x%x", irqs[0]);
3949 	DUMP_FIELD(spu, "0x%x", irqs[1]);
3950 	DUMP_FIELD(spu, "0x%x", irqs[2]);
3951 	DUMP_FIELD(spu, "0x%x", slb_replace);
3952 	DUMP_FIELD(spu, "%d", pid);
3953 	DUMP_FIELD(spu, "0x%p", mm);
3954 	DUMP_FIELD(spu, "0x%p", ctx);
3955 	DUMP_FIELD(spu, "0x%p", rq);
3956 	DUMP_FIELD(spu, "0x%llx", timestamp);
3957 	DUMP_FIELD(spu, "0x%lx", problem_phys);
3958 	DUMP_FIELD(spu, "0x%p", problem);
3959 	DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
3960 			in_be32(&spu->problem->spu_runcntl_RW));
3961 	DUMP_VALUE("0x%x", problem->spu_status_R,
3962 			in_be32(&spu->problem->spu_status_R));
3963 	DUMP_VALUE("0x%x", problem->spu_npc_RW,
3964 			in_be32(&spu->problem->spu_npc_RW));
3965 	DUMP_FIELD(spu, "0x%p", priv2);
3966 	DUMP_FIELD(spu, "0x%p", pdata);
3967 }
3968 
3969 int
spu_inst_dump(unsigned long adr,long count,int praddr)3970 spu_inst_dump(unsigned long adr, long count, int praddr)
3971 {
3972 	return generic_inst_dump(adr, count, praddr, print_insn_spu);
3973 }
3974 
dump_spu_ls(unsigned long num,int subcmd)3975 static void dump_spu_ls(unsigned long num, int subcmd)
3976 {
3977 	unsigned long offset, addr, ls_addr;
3978 
3979 	if (setjmp(bus_error_jmp) == 0) {
3980 		catch_memory_errors = 1;
3981 		sync();
3982 		ls_addr = (unsigned long)spu_info[num].spu->local_store;
3983 		sync();
3984 		__delay(200);
3985 	} else {
3986 		catch_memory_errors = 0;
3987 		printf("*** Error: accessing spu info for spu %ld\n", num);
3988 		return;
3989 	}
3990 	catch_memory_errors = 0;
3991 
3992 	if (scanhex(&offset))
3993 		addr = ls_addr + offset;
3994 	else
3995 		addr = spu_info[num].dump_addr;
3996 
3997 	if (addr >= ls_addr + LS_SIZE) {
3998 		printf("*** Error: address outside of local store\n");
3999 		return;
4000 	}
4001 
4002 	switch (subcmd) {
4003 	case 'i':
4004 		addr += spu_inst_dump(addr, 16, 1);
4005 		last_cmd = "sdi\n";
4006 		break;
4007 	default:
4008 		prdump(addr, 64);
4009 		addr += 64;
4010 		last_cmd = "sd\n";
4011 		break;
4012 	}
4013 
4014 	spu_info[num].dump_addr = addr;
4015 }
4016 
do_spu_cmd(void)4017 static int do_spu_cmd(void)
4018 {
4019 	static unsigned long num = 0;
4020 	int cmd, subcmd = 0;
4021 
4022 	cmd = inchar();
4023 	switch (cmd) {
4024 	case 's':
4025 		stop_spus();
4026 		break;
4027 	case 'r':
4028 		restart_spus();
4029 		break;
4030 	case 'd':
4031 		subcmd = inchar();
4032 		if (isxdigit(subcmd) || subcmd == '\n')
4033 			termch = subcmd;
4034 	case 'f':
4035 		scanhex(&num);
4036 		if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
4037 			printf("*** Error: invalid spu number\n");
4038 			return 0;
4039 		}
4040 
4041 		switch (cmd) {
4042 		case 'f':
4043 			dump_spu_fields(spu_info[num].spu);
4044 			break;
4045 		default:
4046 			dump_spu_ls(num, subcmd);
4047 			break;
4048 		}
4049 
4050 		break;
4051 	default:
4052 		return -1;
4053 	}
4054 
4055 	return 0;
4056 }
4057 #else /* ! CONFIG_SPU_BASE */
do_spu_cmd(void)4058 static int do_spu_cmd(void)
4059 {
4060 	return -1;
4061 }
4062 #endif
4063