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