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