xref: /openbmc/linux/arch/powerpc/xmon/xmon.c (revision 64c70b1c)
1 /*
2  * Routines providing a simple monitor for use on the PowerMac.
3  *
4  * Copyright (C) 1996-2005 Paul Mackerras.
5  * Copyright (C) 2001 PPC64 Team, IBM Corp
6  * Copyrignt (C) 2006 Michael Ellerman, IBM Corp
7  *
8  *      This program is free software; you can redistribute it and/or
9  *      modify it under the terms of the GNU General Public License
10  *      as published by the Free Software Foundation; either version
11  *      2 of the License, or (at your option) any later version.
12  */
13 #include <linux/errno.h>
14 #include <linux/sched.h>
15 #include <linux/smp.h>
16 #include <linux/mm.h>
17 #include <linux/reboot.h>
18 #include <linux/delay.h>
19 #include <linux/kallsyms.h>
20 #include <linux/cpumask.h>
21 #include <linux/module.h>
22 #include <linux/sysrq.h>
23 #include <linux/interrupt.h>
24 #include <linux/irq.h>
25 #include <linux/bug.h>
26 
27 #include <asm/ptrace.h>
28 #include <asm/string.h>
29 #include <asm/prom.h>
30 #include <asm/machdep.h>
31 #include <asm/xmon.h>
32 #include <asm/processor.h>
33 #include <asm/pgtable.h>
34 #include <asm/mmu.h>
35 #include <asm/mmu_context.h>
36 #include <asm/cputable.h>
37 #include <asm/rtas.h>
38 #include <asm/sstep.h>
39 #include <asm/irq_regs.h>
40 #include <asm/spu.h>
41 #include <asm/spu_priv1.h>
42 #include <asm/firmware.h>
43 
44 #ifdef CONFIG_PPC64
45 #include <asm/hvcall.h>
46 #include <asm/paca.h>
47 #include <asm/iseries/it_lp_reg_save.h>
48 #endif
49 
50 #include "nonstdio.h"
51 #include "dis-asm.h"
52 
53 #define scanhex	xmon_scanhex
54 #define skipbl	xmon_skipbl
55 
56 #ifdef CONFIG_SMP
57 cpumask_t cpus_in_xmon = CPU_MASK_NONE;
58 static unsigned long xmon_taken = 1;
59 static int xmon_owner;
60 static int xmon_gate;
61 #endif /* CONFIG_SMP */
62 
63 static unsigned long in_xmon = 0;
64 
65 static unsigned long adrs;
66 static int size = 1;
67 #define MAX_DUMP (128 * 1024)
68 static unsigned long ndump = 64;
69 static unsigned long nidump = 16;
70 static unsigned long ncsum = 4096;
71 static int termch;
72 static char tmpstr[128];
73 
74 #define JMP_BUF_LEN	23
75 static long bus_error_jmp[JMP_BUF_LEN];
76 static int catch_memory_errors;
77 static long *xmon_fault_jmp[NR_CPUS];
78 #define setjmp xmon_setjmp
79 #define longjmp xmon_longjmp
80 
81 /* Breakpoint stuff */
82 struct bpt {
83 	unsigned long	address;
84 	unsigned int	instr[2];
85 	atomic_t	ref_count;
86 	int		enabled;
87 	unsigned long	pad;
88 };
89 
90 /* Bits in bpt.enabled */
91 #define BP_IABR_TE	1		/* IABR translation enabled */
92 #define BP_IABR		2
93 #define BP_TRAP		8
94 #define BP_DABR		0x10
95 
96 #define NBPTS	256
97 static struct bpt bpts[NBPTS];
98 static struct bpt dabr;
99 static struct bpt *iabr;
100 static unsigned bpinstr = 0x7fe00008;	/* trap */
101 
102 #define BP_NUM(bp)	((bp) - bpts + 1)
103 
104 /* Prototypes */
105 static int cmds(struct pt_regs *);
106 static int mread(unsigned long, void *, int);
107 static int mwrite(unsigned long, void *, int);
108 static int handle_fault(struct pt_regs *);
109 static void byterev(unsigned char *, int);
110 static void memex(void);
111 static int bsesc(void);
112 static void dump(void);
113 static void prdump(unsigned long, long);
114 static int ppc_inst_dump(unsigned long, long, int);
115 static void backtrace(struct pt_regs *);
116 static void excprint(struct pt_regs *);
117 static void prregs(struct pt_regs *);
118 static void memops(int);
119 static void memlocate(void);
120 static void memzcan(void);
121 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
122 int skipbl(void);
123 int scanhex(unsigned long *valp);
124 static void scannl(void);
125 static int hexdigit(int);
126 void getstring(char *, int);
127 static void flush_input(void);
128 static int inchar(void);
129 static void take_input(char *);
130 static unsigned long read_spr(int);
131 static void write_spr(int, unsigned long);
132 static void super_regs(void);
133 static void remove_bpts(void);
134 static void insert_bpts(void);
135 static void remove_cpu_bpts(void);
136 static void insert_cpu_bpts(void);
137 static struct bpt *at_breakpoint(unsigned long pc);
138 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
139 static int  do_step(struct pt_regs *);
140 static void bpt_cmds(void);
141 static void cacheflush(void);
142 static int  cpu_cmd(void);
143 static void csum(void);
144 static void bootcmds(void);
145 static void proccall(void);
146 void dump_segments(void);
147 static void symbol_lookup(void);
148 static void xmon_show_stack(unsigned long sp, unsigned long lr,
149 			    unsigned long pc);
150 static void xmon_print_symbol(unsigned long address, const char *mid,
151 			      const char *after);
152 static const char *getvecname(unsigned long vec);
153 
154 static int do_spu_cmd(void);
155 
156 int xmon_no_auto_backtrace;
157 
158 extern void xmon_enter(void);
159 extern void xmon_leave(void);
160 
161 extern long setjmp(long *);
162 extern void longjmp(long *, long);
163 extern void xmon_save_regs(struct pt_regs *);
164 
165 #ifdef CONFIG_PPC64
166 #define REG		"%.16lx"
167 #define REGS_PER_LINE	4
168 #define LAST_VOLATILE	13
169 #else
170 #define REG		"%.8lx"
171 #define REGS_PER_LINE	8
172 #define LAST_VOLATILE	12
173 #endif
174 
175 #define GETWORD(v)	(((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
176 
177 #define isxdigit(c)	(('0' <= (c) && (c) <= '9') \
178 			 || ('a' <= (c) && (c) <= 'f') \
179 			 || ('A' <= (c) && (c) <= 'F'))
180 #define isalnum(c)	(('0' <= (c) && (c) <= '9') \
181 			 || ('a' <= (c) && (c) <= 'z') \
182 			 || ('A' <= (c) && (c) <= 'Z'))
183 #define isspace(c)	(c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
184 
185 static char *help_string = "\
186 Commands:\n\
187   b	show breakpoints\n\
188   bd	set data breakpoint\n\
189   bi	set instruction breakpoint\n\
190   bc	clear breakpoint\n"
191 #ifdef CONFIG_SMP
192   "\
193   c	print cpus stopped in xmon\n\
194   c#	try to switch to cpu number h (in hex)\n"
195 #endif
196   "\
197   C	checksum\n\
198   d	dump bytes\n\
199   di	dump instructions\n\
200   df	dump float values\n\
201   dd	dump double values\n\
202   dr	dump stream of raw bytes\n\
203   e	print exception information\n\
204   f	flush cache\n\
205   la	lookup symbol+offset of specified address\n\
206   ls	lookup address of specified symbol\n\
207   m	examine/change memory\n\
208   mm	move a block of memory\n\
209   ms	set a block of memory\n\
210   md	compare two blocks of memory\n\
211   ml	locate a block of memory\n\
212   mz	zero a block of memory\n\
213   mi	show information about memory allocation\n\
214   p 	call a procedure\n\
215   r	print registers\n\
216   s	single step\n"
217 #ifdef CONFIG_SPU_BASE
218 "  ss	stop execution on all spus\n\
219   sr	restore execution on stopped spus\n\
220   sf  #	dump spu fields for spu # (in hex)\n\
221   sd  #	dump spu local store for spu # (in hex)\n\
222   sdi #	disassemble spu local store for spu # (in hex)\n"
223 #endif
224 "  S	print special registers\n\
225   t	print backtrace\n\
226   x	exit monitor and recover\n\
227   X	exit monitor and dont recover\n"
228 #ifdef CONFIG_PPC64
229 "  u	dump segment table or SLB\n"
230 #endif
231 #ifdef CONFIG_PPC_STD_MMU_32
232 "  u	dump segment registers\n"
233 #endif
234 "  ?	help\n"
235 "  zr	reboot\n\
236   zh	halt\n"
237 ;
238 
239 static struct pt_regs *xmon_regs;
240 
241 static inline void sync(void)
242 {
243 	asm volatile("sync; isync");
244 }
245 
246 static inline void store_inst(void *p)
247 {
248 	asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
249 }
250 
251 static inline void cflush(void *p)
252 {
253 	asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
254 }
255 
256 static inline void cinval(void *p)
257 {
258 	asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
259 }
260 
261 /*
262  * Disable surveillance (the service processor watchdog function)
263  * while we are in xmon.
264  * XXX we should re-enable it when we leave. :)
265  */
266 #define SURVEILLANCE_TOKEN	9000
267 
268 static inline void disable_surveillance(void)
269 {
270 #ifdef CONFIG_PPC_PSERIES
271 	/* Since this can't be a module, args should end up below 4GB. */
272 	static struct rtas_args args;
273 
274 	/*
275 	 * At this point we have got all the cpus we can into
276 	 * xmon, so there is hopefully no other cpu calling RTAS
277 	 * at the moment, even though we don't take rtas.lock.
278 	 * If we did try to take rtas.lock there would be a
279 	 * real possibility of deadlock.
280 	 */
281 	args.token = rtas_token("set-indicator");
282 	if (args.token == RTAS_UNKNOWN_SERVICE)
283 		return;
284 	args.nargs = 3;
285 	args.nret = 1;
286 	args.rets = &args.args[3];
287 	args.args[0] = SURVEILLANCE_TOKEN;
288 	args.args[1] = 0;
289 	args.args[2] = 0;
290 	enter_rtas(__pa(&args));
291 #endif /* CONFIG_PPC_PSERIES */
292 }
293 
294 #ifdef CONFIG_SMP
295 static int xmon_speaker;
296 
297 static void get_output_lock(void)
298 {
299 	int me = smp_processor_id() + 0x100;
300 	int last_speaker = 0, prev;
301 	long timeout;
302 
303 	if (xmon_speaker == me)
304 		return;
305 	for (;;) {
306 		if (xmon_speaker == 0) {
307 			last_speaker = cmpxchg(&xmon_speaker, 0, me);
308 			if (last_speaker == 0)
309 				return;
310 		}
311 		timeout = 10000000;
312 		while (xmon_speaker == last_speaker) {
313 			if (--timeout > 0)
314 				continue;
315 			/* hostile takeover */
316 			prev = cmpxchg(&xmon_speaker, last_speaker, me);
317 			if (prev == last_speaker)
318 				return;
319 			break;
320 		}
321 	}
322 }
323 
324 static void release_output_lock(void)
325 {
326 	xmon_speaker = 0;
327 }
328 #endif
329 
330 static int xmon_core(struct pt_regs *regs, int fromipi)
331 {
332 	int cmd = 0;
333 	struct bpt *bp;
334 	long recurse_jmp[JMP_BUF_LEN];
335 	unsigned long offset;
336 	unsigned long flags;
337 #ifdef CONFIG_SMP
338 	int cpu;
339 	int secondary;
340 	unsigned long timeout;
341 #endif
342 
343 	local_irq_save(flags);
344 
345 	bp = in_breakpoint_table(regs->nip, &offset);
346 	if (bp != NULL) {
347 		regs->nip = bp->address + offset;
348 		atomic_dec(&bp->ref_count);
349 	}
350 
351 	remove_cpu_bpts();
352 
353 #ifdef CONFIG_SMP
354 	cpu = smp_processor_id();
355 	if (cpu_isset(cpu, cpus_in_xmon)) {
356 		get_output_lock();
357 		excprint(regs);
358 		printf("cpu 0x%x: Exception %lx %s in xmon, "
359 		       "returning to main loop\n",
360 		       cpu, regs->trap, getvecname(TRAP(regs)));
361 		release_output_lock();
362 		longjmp(xmon_fault_jmp[cpu], 1);
363 	}
364 
365 	if (setjmp(recurse_jmp) != 0) {
366 		if (!in_xmon || !xmon_gate) {
367 			get_output_lock();
368 			printf("xmon: WARNING: bad recursive fault "
369 			       "on cpu 0x%x\n", cpu);
370 			release_output_lock();
371 			goto waiting;
372 		}
373 		secondary = !(xmon_taken && cpu == xmon_owner);
374 		goto cmdloop;
375 	}
376 
377 	xmon_fault_jmp[cpu] = recurse_jmp;
378 	cpu_set(cpu, cpus_in_xmon);
379 
380 	bp = NULL;
381 	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
382 		bp = at_breakpoint(regs->nip);
383 	if (bp || (regs->msr & MSR_RI) == 0)
384 		fromipi = 0;
385 
386 	if (!fromipi) {
387 		get_output_lock();
388 		excprint(regs);
389 		if (bp) {
390 			printf("cpu 0x%x stopped at breakpoint 0x%x (",
391 			       cpu, BP_NUM(bp));
392 			xmon_print_symbol(regs->nip, " ", ")\n");
393 		}
394 		if ((regs->msr & MSR_RI) == 0)
395 			printf("WARNING: exception is not recoverable, "
396 			       "can't continue\n");
397 		release_output_lock();
398 	}
399 
400  waiting:
401 	secondary = 1;
402 	while (secondary && !xmon_gate) {
403 		if (in_xmon == 0) {
404 			if (fromipi)
405 				goto leave;
406 			secondary = test_and_set_bit(0, &in_xmon);
407 		}
408 		barrier();
409 	}
410 
411 	if (!secondary && !xmon_gate) {
412 		/* we are the first cpu to come in */
413 		/* interrupt other cpu(s) */
414 		int ncpus = num_online_cpus();
415 
416 		xmon_owner = cpu;
417 		mb();
418 		if (ncpus > 1) {
419 			smp_send_debugger_break(MSG_ALL_BUT_SELF);
420 			/* wait for other cpus to come in */
421 			for (timeout = 100000000; timeout != 0; --timeout) {
422 				if (cpus_weight(cpus_in_xmon) >= ncpus)
423 					break;
424 				barrier();
425 			}
426 		}
427 		remove_bpts();
428 		disable_surveillance();
429 		/* for breakpoint or single step, print the current instr. */
430 		if (bp || TRAP(regs) == 0xd00)
431 			ppc_inst_dump(regs->nip, 1, 0);
432 		printf("enter ? for help\n");
433 		mb();
434 		xmon_gate = 1;
435 		barrier();
436 	}
437 
438  cmdloop:
439 	while (in_xmon) {
440 		if (secondary) {
441 			if (cpu == xmon_owner) {
442 				if (!test_and_set_bit(0, &xmon_taken)) {
443 					secondary = 0;
444 					continue;
445 				}
446 				/* missed it */
447 				while (cpu == xmon_owner)
448 					barrier();
449 			}
450 			barrier();
451 		} else {
452 			cmd = cmds(regs);
453 			if (cmd != 0) {
454 				/* exiting xmon */
455 				insert_bpts();
456 				xmon_gate = 0;
457 				wmb();
458 				in_xmon = 0;
459 				break;
460 			}
461 			/* have switched to some other cpu */
462 			secondary = 1;
463 		}
464 	}
465  leave:
466 	cpu_clear(cpu, cpus_in_xmon);
467 	xmon_fault_jmp[cpu] = NULL;
468 #else
469 	/* UP is simple... */
470 	if (in_xmon) {
471 		printf("Exception %lx %s in xmon, returning to main loop\n",
472 		       regs->trap, getvecname(TRAP(regs)));
473 		longjmp(xmon_fault_jmp[0], 1);
474 	}
475 	if (setjmp(recurse_jmp) == 0) {
476 		xmon_fault_jmp[0] = recurse_jmp;
477 		in_xmon = 1;
478 
479 		excprint(regs);
480 		bp = at_breakpoint(regs->nip);
481 		if (bp) {
482 			printf("Stopped at breakpoint %x (", BP_NUM(bp));
483 			xmon_print_symbol(regs->nip, " ", ")\n");
484 		}
485 		if ((regs->msr & MSR_RI) == 0)
486 			printf("WARNING: exception is not recoverable, "
487 			       "can't continue\n");
488 		remove_bpts();
489 		disable_surveillance();
490 		/* for breakpoint or single step, print the current instr. */
491 		if (bp || TRAP(regs) == 0xd00)
492 			ppc_inst_dump(regs->nip, 1, 0);
493 		printf("enter ? for help\n");
494 	}
495 
496 	cmd = cmds(regs);
497 
498 	insert_bpts();
499 	in_xmon = 0;
500 #endif
501 
502 	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
503 		bp = at_breakpoint(regs->nip);
504 		if (bp != NULL) {
505 			int stepped = emulate_step(regs, bp->instr[0]);
506 			if (stepped == 0) {
507 				regs->nip = (unsigned long) &bp->instr[0];
508 				atomic_inc(&bp->ref_count);
509 			} else if (stepped < 0) {
510 				printf("Couldn't single-step %s instruction\n",
511 				    (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
512 			}
513 		}
514 	}
515 
516 	insert_cpu_bpts();
517 
518 	local_irq_restore(flags);
519 
520 	return cmd != 'X' && cmd != EOF;
521 }
522 
523 int xmon(struct pt_regs *excp)
524 {
525 	struct pt_regs regs;
526 
527 	if (excp == NULL) {
528 		xmon_save_regs(&regs);
529 		excp = &regs;
530 	}
531 
532 	return xmon_core(excp, 0);
533 }
534 EXPORT_SYMBOL(xmon);
535 
536 irqreturn_t xmon_irq(int irq, void *d)
537 {
538 	unsigned long flags;
539 	local_irq_save(flags);
540 	printf("Keyboard interrupt\n");
541 	xmon(get_irq_regs());
542 	local_irq_restore(flags);
543 	return IRQ_HANDLED;
544 }
545 
546 static int xmon_bpt(struct pt_regs *regs)
547 {
548 	struct bpt *bp;
549 	unsigned long offset;
550 
551 	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
552 		return 0;
553 
554 	/* Are we at the trap at bp->instr[1] for some bp? */
555 	bp = in_breakpoint_table(regs->nip, &offset);
556 	if (bp != NULL && offset == 4) {
557 		regs->nip = bp->address + 4;
558 		atomic_dec(&bp->ref_count);
559 		return 1;
560 	}
561 
562 	/* Are we at a breakpoint? */
563 	bp = at_breakpoint(regs->nip);
564 	if (!bp)
565 		return 0;
566 
567 	xmon_core(regs, 0);
568 
569 	return 1;
570 }
571 
572 static int xmon_sstep(struct pt_regs *regs)
573 {
574 	if (user_mode(regs))
575 		return 0;
576 	xmon_core(regs, 0);
577 	return 1;
578 }
579 
580 static int xmon_dabr_match(struct pt_regs *regs)
581 {
582 	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
583 		return 0;
584 	if (dabr.enabled == 0)
585 		return 0;
586 	xmon_core(regs, 0);
587 	return 1;
588 }
589 
590 static int xmon_iabr_match(struct pt_regs *regs)
591 {
592 	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
593 		return 0;
594 	if (iabr == 0)
595 		return 0;
596 	xmon_core(regs, 0);
597 	return 1;
598 }
599 
600 static int xmon_ipi(struct pt_regs *regs)
601 {
602 #ifdef CONFIG_SMP
603 	if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
604 		xmon_core(regs, 1);
605 #endif
606 	return 0;
607 }
608 
609 static int xmon_fault_handler(struct pt_regs *regs)
610 {
611 	struct bpt *bp;
612 	unsigned long offset;
613 
614 	if (in_xmon && catch_memory_errors)
615 		handle_fault(regs);	/* doesn't return */
616 
617 	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
618 		bp = in_breakpoint_table(regs->nip, &offset);
619 		if (bp != NULL) {
620 			regs->nip = bp->address + offset;
621 			atomic_dec(&bp->ref_count);
622 		}
623 	}
624 
625 	return 0;
626 }
627 
628 static struct bpt *at_breakpoint(unsigned long pc)
629 {
630 	int i;
631 	struct bpt *bp;
632 
633 	bp = bpts;
634 	for (i = 0; i < NBPTS; ++i, ++bp)
635 		if (bp->enabled && pc == bp->address)
636 			return bp;
637 	return NULL;
638 }
639 
640 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
641 {
642 	unsigned long off;
643 
644 	off = nip - (unsigned long) bpts;
645 	if (off >= sizeof(bpts))
646 		return NULL;
647 	off %= sizeof(struct bpt);
648 	if (off != offsetof(struct bpt, instr[0])
649 	    && off != offsetof(struct bpt, instr[1]))
650 		return NULL;
651 	*offp = off - offsetof(struct bpt, instr[0]);
652 	return (struct bpt *) (nip - off);
653 }
654 
655 static struct bpt *new_breakpoint(unsigned long a)
656 {
657 	struct bpt *bp;
658 
659 	a &= ~3UL;
660 	bp = at_breakpoint(a);
661 	if (bp)
662 		return bp;
663 
664 	for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
665 		if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
666 			bp->address = a;
667 			bp->instr[1] = bpinstr;
668 			store_inst(&bp->instr[1]);
669 			return bp;
670 		}
671 	}
672 
673 	printf("Sorry, no free breakpoints.  Please clear one first.\n");
674 	return NULL;
675 }
676 
677 static void insert_bpts(void)
678 {
679 	int i;
680 	struct bpt *bp;
681 
682 	bp = bpts;
683 	for (i = 0; i < NBPTS; ++i, ++bp) {
684 		if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
685 			continue;
686 		if (mread(bp->address, &bp->instr[0], 4) != 4) {
687 			printf("Couldn't read instruction at %lx, "
688 			       "disabling breakpoint there\n", bp->address);
689 			bp->enabled = 0;
690 			continue;
691 		}
692 		if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
693 			printf("Breakpoint at %lx is on an mtmsrd or rfid "
694 			       "instruction, disabling it\n", bp->address);
695 			bp->enabled = 0;
696 			continue;
697 		}
698 		store_inst(&bp->instr[0]);
699 		if (bp->enabled & BP_IABR)
700 			continue;
701 		if (mwrite(bp->address, &bpinstr, 4) != 4) {
702 			printf("Couldn't write instruction at %lx, "
703 			       "disabling breakpoint there\n", bp->address);
704 			bp->enabled &= ~BP_TRAP;
705 			continue;
706 		}
707 		store_inst((void *)bp->address);
708 	}
709 }
710 
711 static void insert_cpu_bpts(void)
712 {
713 	if (dabr.enabled)
714 		set_dabr(dabr.address | (dabr.enabled & 7));
715 	if (iabr && cpu_has_feature(CPU_FTR_IABR))
716 		mtspr(SPRN_IABR, iabr->address
717 			 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
718 }
719 
720 static void remove_bpts(void)
721 {
722 	int i;
723 	struct bpt *bp;
724 	unsigned instr;
725 
726 	bp = bpts;
727 	for (i = 0; i < NBPTS; ++i, ++bp) {
728 		if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
729 			continue;
730 		if (mread(bp->address, &instr, 4) == 4
731 		    && instr == bpinstr
732 		    && mwrite(bp->address, &bp->instr, 4) != 4)
733 			printf("Couldn't remove breakpoint at %lx\n",
734 			       bp->address);
735 		else
736 			store_inst((void *)bp->address);
737 	}
738 }
739 
740 static void remove_cpu_bpts(void)
741 {
742 	set_dabr(0);
743 	if (cpu_has_feature(CPU_FTR_IABR))
744 		mtspr(SPRN_IABR, 0);
745 }
746 
747 /* Command interpreting routine */
748 static char *last_cmd;
749 
750 static int
751 cmds(struct pt_regs *excp)
752 {
753 	int cmd = 0;
754 
755 	last_cmd = NULL;
756 	xmon_regs = excp;
757 
758 	if (!xmon_no_auto_backtrace) {
759 		xmon_no_auto_backtrace = 1;
760 		xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
761 	}
762 
763 	for(;;) {
764 #ifdef CONFIG_SMP
765 		printf("%x:", smp_processor_id());
766 #endif /* CONFIG_SMP */
767 		printf("mon> ");
768 		flush_input();
769 		termch = 0;
770 		cmd = skipbl();
771 		if( cmd == '\n' ) {
772 			if (last_cmd == NULL)
773 				continue;
774 			take_input(last_cmd);
775 			last_cmd = NULL;
776 			cmd = inchar();
777 		}
778 		switch (cmd) {
779 		case 'm':
780 			cmd = inchar();
781 			switch (cmd) {
782 			case 'm':
783 			case 's':
784 			case 'd':
785 				memops(cmd);
786 				break;
787 			case 'l':
788 				memlocate();
789 				break;
790 			case 'z':
791 				memzcan();
792 				break;
793 			case 'i':
794 				show_mem();
795 				break;
796 			default:
797 				termch = cmd;
798 				memex();
799 			}
800 			break;
801 		case 'd':
802 			dump();
803 			break;
804 		case 'l':
805 			symbol_lookup();
806 			break;
807 		case 'r':
808 			prregs(excp);	/* print regs */
809 			break;
810 		case 'e':
811 			excprint(excp);
812 			break;
813 		case 'S':
814 			super_regs();
815 			break;
816 		case 't':
817 			backtrace(excp);
818 			break;
819 		case 'f':
820 			cacheflush();
821 			break;
822 		case 's':
823 			if (do_spu_cmd() == 0)
824 				break;
825 			if (do_step(excp))
826 				return cmd;
827 			break;
828 		case 'x':
829 		case 'X':
830 			return cmd;
831 		case EOF:
832 			printf(" <no input ...>\n");
833 			mdelay(2000);
834 			return cmd;
835 		case '?':
836 			printf(help_string);
837 			break;
838 		case 'b':
839 			bpt_cmds();
840 			break;
841 		case 'C':
842 			csum();
843 			break;
844 		case 'c':
845 			if (cpu_cmd())
846 				return 0;
847 			break;
848 		case 'z':
849 			bootcmds();
850 			break;
851 		case 'p':
852 			proccall();
853 			break;
854 #ifdef CONFIG_PPC_STD_MMU
855 		case 'u':
856 			dump_segments();
857 			break;
858 #endif
859 		default:
860 			printf("Unrecognized command: ");
861 		        do {
862 				if (' ' < cmd && cmd <= '~')
863 					putchar(cmd);
864 				else
865 					printf("\\x%x", cmd);
866 				cmd = inchar();
867 		        } while (cmd != '\n');
868 			printf(" (type ? for help)\n");
869 			break;
870 		}
871 	}
872 }
873 
874 /*
875  * Step a single instruction.
876  * Some instructions we emulate, others we execute with MSR_SE set.
877  */
878 static int do_step(struct pt_regs *regs)
879 {
880 	unsigned int instr;
881 	int stepped;
882 
883 	/* check we are in 64-bit kernel mode, translation enabled */
884 	if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
885 		if (mread(regs->nip, &instr, 4) == 4) {
886 			stepped = emulate_step(regs, instr);
887 			if (stepped < 0) {
888 				printf("Couldn't single-step %s instruction\n",
889 				       (IS_RFID(instr)? "rfid": "mtmsrd"));
890 				return 0;
891 			}
892 			if (stepped > 0) {
893 				regs->trap = 0xd00 | (regs->trap & 1);
894 				printf("stepped to ");
895 				xmon_print_symbol(regs->nip, " ", "\n");
896 				ppc_inst_dump(regs->nip, 1, 0);
897 				return 0;
898 			}
899 		}
900 	}
901 	regs->msr |= MSR_SE;
902 	return 1;
903 }
904 
905 static void bootcmds(void)
906 {
907 	int cmd;
908 
909 	cmd = inchar();
910 	if (cmd == 'r')
911 		ppc_md.restart(NULL);
912 	else if (cmd == 'h')
913 		ppc_md.halt();
914 	else if (cmd == 'p')
915 		ppc_md.power_off();
916 }
917 
918 static int cpu_cmd(void)
919 {
920 #ifdef CONFIG_SMP
921 	unsigned long cpu;
922 	int timeout;
923 	int count;
924 
925 	if (!scanhex(&cpu)) {
926 		/* print cpus waiting or in xmon */
927 		printf("cpus stopped:");
928 		count = 0;
929 		for (cpu = 0; cpu < NR_CPUS; ++cpu) {
930 			if (cpu_isset(cpu, cpus_in_xmon)) {
931 				if (count == 0)
932 					printf(" %x", cpu);
933 				++count;
934 			} else {
935 				if (count > 1)
936 					printf("-%x", cpu - 1);
937 				count = 0;
938 			}
939 		}
940 		if (count > 1)
941 			printf("-%x", NR_CPUS - 1);
942 		printf("\n");
943 		return 0;
944 	}
945 	/* try to switch to cpu specified */
946 	if (!cpu_isset(cpu, cpus_in_xmon)) {
947 		printf("cpu 0x%x isn't in xmon\n", cpu);
948 		return 0;
949 	}
950 	xmon_taken = 0;
951 	mb();
952 	xmon_owner = cpu;
953 	timeout = 10000000;
954 	while (!xmon_taken) {
955 		if (--timeout == 0) {
956 			if (test_and_set_bit(0, &xmon_taken))
957 				break;
958 			/* take control back */
959 			mb();
960 			xmon_owner = smp_processor_id();
961 			printf("cpu %u didn't take control\n", cpu);
962 			return 0;
963 		}
964 		barrier();
965 	}
966 	return 1;
967 #else
968 	return 0;
969 #endif /* CONFIG_SMP */
970 }
971 
972 static unsigned short fcstab[256] = {
973 	0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
974 	0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
975 	0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
976 	0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
977 	0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
978 	0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
979 	0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
980 	0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
981 	0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
982 	0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
983 	0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
984 	0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
985 	0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
986 	0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
987 	0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
988 	0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
989 	0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
990 	0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
991 	0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
992 	0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
993 	0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
994 	0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
995 	0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
996 	0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
997 	0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
998 	0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
999 	0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1000 	0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1001 	0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1002 	0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1003 	0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1004 	0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1005 };
1006 
1007 #define FCS(fcs, c)	(((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1008 
1009 static void
1010 csum(void)
1011 {
1012 	unsigned int i;
1013 	unsigned short fcs;
1014 	unsigned char v;
1015 
1016 	if (!scanhex(&adrs))
1017 		return;
1018 	if (!scanhex(&ncsum))
1019 		return;
1020 	fcs = 0xffff;
1021 	for (i = 0; i < ncsum; ++i) {
1022 		if (mread(adrs+i, &v, 1) == 0) {
1023 			printf("csum stopped at %x\n", adrs+i);
1024 			break;
1025 		}
1026 		fcs = FCS(fcs, v);
1027 	}
1028 	printf("%x\n", fcs);
1029 }
1030 
1031 /*
1032  * Check if this is a suitable place to put a breakpoint.
1033  */
1034 static long check_bp_loc(unsigned long addr)
1035 {
1036 	unsigned int instr;
1037 
1038 	addr &= ~3;
1039 	if (!is_kernel_addr(addr)) {
1040 		printf("Breakpoints may only be placed at kernel addresses\n");
1041 		return 0;
1042 	}
1043 	if (!mread(addr, &instr, sizeof(instr))) {
1044 		printf("Can't read instruction at address %lx\n", addr);
1045 		return 0;
1046 	}
1047 	if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1048 		printf("Breakpoints may not be placed on mtmsrd or rfid "
1049 		       "instructions\n");
1050 		return 0;
1051 	}
1052 	return 1;
1053 }
1054 
1055 static char *breakpoint_help_string =
1056     "Breakpoint command usage:\n"
1057     "b                show breakpoints\n"
1058     "b <addr> [cnt]   set breakpoint at given instr addr\n"
1059     "bc               clear all breakpoints\n"
1060     "bc <n/addr>      clear breakpoint number n or at addr\n"
1061     "bi <addr> [cnt]  set hardware instr breakpoint (POWER3/RS64 only)\n"
1062     "bd <addr> [cnt]  set hardware data breakpoint\n"
1063     "";
1064 
1065 static void
1066 bpt_cmds(void)
1067 {
1068 	int cmd;
1069 	unsigned long a;
1070 	int mode, i;
1071 	struct bpt *bp;
1072 	const char badaddr[] = "Only kernel addresses are permitted "
1073 		"for breakpoints\n";
1074 
1075 	cmd = inchar();
1076 	switch (cmd) {
1077 #ifndef CONFIG_8xx
1078 	case 'd':	/* bd - hardware data breakpoint */
1079 		mode = 7;
1080 		cmd = inchar();
1081 		if (cmd == 'r')
1082 			mode = 5;
1083 		else if (cmd == 'w')
1084 			mode = 6;
1085 		else
1086 			termch = cmd;
1087 		dabr.address = 0;
1088 		dabr.enabled = 0;
1089 		if (scanhex(&dabr.address)) {
1090 			if (!is_kernel_addr(dabr.address)) {
1091 				printf(badaddr);
1092 				break;
1093 			}
1094 			dabr.address &= ~7;
1095 			dabr.enabled = mode | BP_DABR;
1096 		}
1097 		break;
1098 
1099 	case 'i':	/* bi - hardware instr breakpoint */
1100 		if (!cpu_has_feature(CPU_FTR_IABR)) {
1101 			printf("Hardware instruction breakpoint "
1102 			       "not supported on this cpu\n");
1103 			break;
1104 		}
1105 		if (iabr) {
1106 			iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1107 			iabr = NULL;
1108 		}
1109 		if (!scanhex(&a))
1110 			break;
1111 		if (!check_bp_loc(a))
1112 			break;
1113 		bp = new_breakpoint(a);
1114 		if (bp != NULL) {
1115 			bp->enabled |= BP_IABR | BP_IABR_TE;
1116 			iabr = bp;
1117 		}
1118 		break;
1119 #endif
1120 
1121 	case 'c':
1122 		if (!scanhex(&a)) {
1123 			/* clear all breakpoints */
1124 			for (i = 0; i < NBPTS; ++i)
1125 				bpts[i].enabled = 0;
1126 			iabr = NULL;
1127 			dabr.enabled = 0;
1128 			printf("All breakpoints cleared\n");
1129 			break;
1130 		}
1131 
1132 		if (a <= NBPTS && a >= 1) {
1133 			/* assume a breakpoint number */
1134 			bp = &bpts[a-1];	/* bp nums are 1 based */
1135 		} else {
1136 			/* assume a breakpoint address */
1137 			bp = at_breakpoint(a);
1138 			if (bp == 0) {
1139 				printf("No breakpoint at %x\n", a);
1140 				break;
1141 			}
1142 		}
1143 
1144 		printf("Cleared breakpoint %x (", BP_NUM(bp));
1145 		xmon_print_symbol(bp->address, " ", ")\n");
1146 		bp->enabled = 0;
1147 		break;
1148 
1149 	default:
1150 		termch = cmd;
1151 	        cmd = skipbl();
1152 		if (cmd == '?') {
1153 			printf(breakpoint_help_string);
1154 			break;
1155 		}
1156 		termch = cmd;
1157 		if (!scanhex(&a)) {
1158 			/* print all breakpoints */
1159 			printf("   type            address\n");
1160 			if (dabr.enabled) {
1161 				printf("   data   "REG"  [", dabr.address);
1162 				if (dabr.enabled & 1)
1163 					printf("r");
1164 				if (dabr.enabled & 2)
1165 					printf("w");
1166 				printf("]\n");
1167 			}
1168 			for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1169 				if (!bp->enabled)
1170 					continue;
1171 				printf("%2x %s   ", BP_NUM(bp),
1172 				    (bp->enabled & BP_IABR)? "inst": "trap");
1173 				xmon_print_symbol(bp->address, "  ", "\n");
1174 			}
1175 			break;
1176 		}
1177 
1178 		if (!check_bp_loc(a))
1179 			break;
1180 		bp = new_breakpoint(a);
1181 		if (bp != NULL)
1182 			bp->enabled |= BP_TRAP;
1183 		break;
1184 	}
1185 }
1186 
1187 /* Very cheap human name for vector lookup. */
1188 static
1189 const char *getvecname(unsigned long vec)
1190 {
1191 	char *ret;
1192 
1193 	switch (vec) {
1194 	case 0x100:	ret = "(System Reset)"; break;
1195 	case 0x200:	ret = "(Machine Check)"; break;
1196 	case 0x300:	ret = "(Data Access)"; break;
1197 	case 0x380:	ret = "(Data SLB Access)"; break;
1198 	case 0x400:	ret = "(Instruction Access)"; break;
1199 	case 0x480:	ret = "(Instruction SLB Access)"; break;
1200 	case 0x500:	ret = "(Hardware Interrupt)"; break;
1201 	case 0x600:	ret = "(Alignment)"; break;
1202 	case 0x700:	ret = "(Program Check)"; break;
1203 	case 0x800:	ret = "(FPU Unavailable)"; break;
1204 	case 0x900:	ret = "(Decrementer)"; break;
1205 	case 0xc00:	ret = "(System Call)"; break;
1206 	case 0xd00:	ret = "(Single Step)"; break;
1207 	case 0xf00:	ret = "(Performance Monitor)"; break;
1208 	case 0xf20:	ret = "(Altivec Unavailable)"; break;
1209 	case 0x1300:	ret = "(Instruction Breakpoint)"; break;
1210 	default: ret = "";
1211 	}
1212 	return ret;
1213 }
1214 
1215 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1216 				unsigned long *endp)
1217 {
1218 	unsigned long size, offset;
1219 	const char *name;
1220 
1221 	*startp = *endp = 0;
1222 	if (pc == 0)
1223 		return;
1224 	if (setjmp(bus_error_jmp) == 0) {
1225 		catch_memory_errors = 1;
1226 		sync();
1227 		name = kallsyms_lookup(pc, &size, &offset, NULL, tmpstr);
1228 		if (name != NULL) {
1229 			*startp = pc - offset;
1230 			*endp = pc - offset + size;
1231 		}
1232 		sync();
1233 	}
1234 	catch_memory_errors = 0;
1235 }
1236 
1237 static int xmon_depth_to_print = 64;
1238 
1239 #ifdef CONFIG_PPC64
1240 #define LRSAVE_OFFSET		0x10
1241 #define REG_FRAME_MARKER	0x7265677368657265ul	/* "regshere" */
1242 #define MARKER_OFFSET		0x60
1243 #define REGS_OFFSET		0x70
1244 #else
1245 #define LRSAVE_OFFSET		4
1246 #define REG_FRAME_MARKER	0x72656773
1247 #define MARKER_OFFSET		8
1248 #define REGS_OFFSET		16
1249 #endif
1250 
1251 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1252 			    unsigned long pc)
1253 {
1254 	unsigned long ip;
1255 	unsigned long newsp;
1256 	unsigned long marker;
1257 	int count = 0;
1258 	struct pt_regs regs;
1259 
1260 	do {
1261 		if (sp < PAGE_OFFSET) {
1262 			if (sp != 0)
1263 				printf("SP (%lx) is in userspace\n", sp);
1264 			break;
1265 		}
1266 
1267 		if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1268 		    || !mread(sp, &newsp, sizeof(unsigned long))) {
1269 			printf("Couldn't read stack frame at %lx\n", sp);
1270 			break;
1271 		}
1272 
1273 		/*
1274 		 * For the first stack frame, try to work out if
1275 		 * LR and/or the saved LR value in the bottommost
1276 		 * stack frame are valid.
1277 		 */
1278 		if ((pc | lr) != 0) {
1279 			unsigned long fnstart, fnend;
1280 			unsigned long nextip;
1281 			int printip = 1;
1282 
1283 			get_function_bounds(pc, &fnstart, &fnend);
1284 			nextip = 0;
1285 			if (newsp > sp)
1286 				mread(newsp + LRSAVE_OFFSET, &nextip,
1287 				      sizeof(unsigned long));
1288 			if (lr == ip) {
1289 				if (lr < PAGE_OFFSET
1290 				    || (fnstart <= lr && lr < fnend))
1291 					printip = 0;
1292 			} else if (lr == nextip) {
1293 				printip = 0;
1294 			} else if (lr >= PAGE_OFFSET
1295 				   && !(fnstart <= lr && lr < fnend)) {
1296 				printf("[link register   ] ");
1297 				xmon_print_symbol(lr, " ", "\n");
1298 			}
1299 			if (printip) {
1300 				printf("["REG"] ", sp);
1301 				xmon_print_symbol(ip, " ", " (unreliable)\n");
1302 			}
1303 			pc = lr = 0;
1304 
1305 		} else {
1306 			printf("["REG"] ", sp);
1307 			xmon_print_symbol(ip, " ", "\n");
1308 		}
1309 
1310 		/* Look for "regshere" marker to see if this is
1311 		   an exception frame. */
1312 		if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1313 		    && marker == REG_FRAME_MARKER) {
1314 			if (mread(sp + REGS_OFFSET, &regs, sizeof(regs))
1315 			    != sizeof(regs)) {
1316 				printf("Couldn't read registers at %lx\n",
1317 				       sp + REGS_OFFSET);
1318 				break;
1319 			}
1320                         printf("--- Exception: %lx %s at ", regs.trap,
1321 			       getvecname(TRAP(&regs)));
1322 			pc = regs.nip;
1323 			lr = regs.link;
1324 			xmon_print_symbol(pc, " ", "\n");
1325 		}
1326 
1327 		if (newsp == 0)
1328 			break;
1329 
1330 		sp = newsp;
1331 	} while (count++ < xmon_depth_to_print);
1332 }
1333 
1334 static void backtrace(struct pt_regs *excp)
1335 {
1336 	unsigned long sp;
1337 
1338 	if (scanhex(&sp))
1339 		xmon_show_stack(sp, 0, 0);
1340 	else
1341 		xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1342 	scannl();
1343 }
1344 
1345 static void print_bug_trap(struct pt_regs *regs)
1346 {
1347 	const struct bug_entry *bug;
1348 	unsigned long addr;
1349 
1350 	if (regs->msr & MSR_PR)
1351 		return;		/* not in kernel */
1352 	addr = regs->nip;	/* address of trap instruction */
1353 	if (addr < PAGE_OFFSET)
1354 		return;
1355 	bug = find_bug(regs->nip);
1356 	if (bug == NULL)
1357 		return;
1358 	if (is_warning_bug(bug))
1359 		return;
1360 
1361 #ifdef CONFIG_DEBUG_BUGVERBOSE
1362 	printf("kernel BUG at %s:%u!\n",
1363 	       bug->file, bug->line);
1364 #else
1365 	printf("kernel BUG at %p!\n", (void *)bug->bug_addr);
1366 #endif
1367 }
1368 
1369 void excprint(struct pt_regs *fp)
1370 {
1371 	unsigned long trap;
1372 
1373 #ifdef CONFIG_SMP
1374 	printf("cpu 0x%x: ", smp_processor_id());
1375 #endif /* CONFIG_SMP */
1376 
1377 	trap = TRAP(fp);
1378 	printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1379 	printf("    pc: ");
1380 	xmon_print_symbol(fp->nip, ": ", "\n");
1381 
1382 	printf("    lr: ", fp->link);
1383 	xmon_print_symbol(fp->link, ": ", "\n");
1384 
1385 	printf("    sp: %lx\n", fp->gpr[1]);
1386 	printf("   msr: %lx\n", fp->msr);
1387 
1388 	if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1389 		printf("   dar: %lx\n", fp->dar);
1390 		if (trap != 0x380)
1391 			printf(" dsisr: %lx\n", fp->dsisr);
1392 	}
1393 
1394 	printf("  current = 0x%lx\n", current);
1395 #ifdef CONFIG_PPC64
1396 	printf("  paca    = 0x%lx\n", get_paca());
1397 #endif
1398 	if (current) {
1399 		printf("    pid   = %ld, comm = %s\n",
1400 		       current->pid, current->comm);
1401 	}
1402 
1403 	if (trap == 0x700)
1404 		print_bug_trap(fp);
1405 }
1406 
1407 void prregs(struct pt_regs *fp)
1408 {
1409 	int n, trap;
1410 	unsigned long base;
1411 	struct pt_regs regs;
1412 
1413 	if (scanhex(&base)) {
1414 		if (setjmp(bus_error_jmp) == 0) {
1415 			catch_memory_errors = 1;
1416 			sync();
1417 			regs = *(struct pt_regs *)base;
1418 			sync();
1419 			__delay(200);
1420 		} else {
1421 			catch_memory_errors = 0;
1422 			printf("*** Error reading registers from "REG"\n",
1423 			       base);
1424 			return;
1425 		}
1426 		catch_memory_errors = 0;
1427 		fp = &regs;
1428 	}
1429 
1430 #ifdef CONFIG_PPC64
1431 	if (FULL_REGS(fp)) {
1432 		for (n = 0; n < 16; ++n)
1433 			printf("R%.2ld = "REG"   R%.2ld = "REG"\n",
1434 			       n, fp->gpr[n], n+16, fp->gpr[n+16]);
1435 	} else {
1436 		for (n = 0; n < 7; ++n)
1437 			printf("R%.2ld = "REG"   R%.2ld = "REG"\n",
1438 			       n, fp->gpr[n], n+7, fp->gpr[n+7]);
1439 	}
1440 #else
1441 	for (n = 0; n < 32; ++n) {
1442 		printf("R%.2d = %.8x%s", n, fp->gpr[n],
1443 		       (n & 3) == 3? "\n": "   ");
1444 		if (n == 12 && !FULL_REGS(fp)) {
1445 			printf("\n");
1446 			break;
1447 		}
1448 	}
1449 #endif
1450 	printf("pc  = ");
1451 	xmon_print_symbol(fp->nip, " ", "\n");
1452 	printf("lr  = ");
1453 	xmon_print_symbol(fp->link, " ", "\n");
1454 	printf("msr = "REG"   cr  = %.8lx\n", fp->msr, fp->ccr);
1455 	printf("ctr = "REG"   xer = "REG"   trap = %4lx\n",
1456 	       fp->ctr, fp->xer, fp->trap);
1457 	trap = TRAP(fp);
1458 	if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1459 		printf("dar = "REG"   dsisr = %.8lx\n", fp->dar, fp->dsisr);
1460 }
1461 
1462 void cacheflush(void)
1463 {
1464 	int cmd;
1465 	unsigned long nflush;
1466 
1467 	cmd = inchar();
1468 	if (cmd != 'i')
1469 		termch = cmd;
1470 	scanhex((void *)&adrs);
1471 	if (termch != '\n')
1472 		termch = 0;
1473 	nflush = 1;
1474 	scanhex(&nflush);
1475 	nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1476 	if (setjmp(bus_error_jmp) == 0) {
1477 		catch_memory_errors = 1;
1478 		sync();
1479 
1480 		if (cmd != 'i') {
1481 			for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1482 				cflush((void *) adrs);
1483 		} else {
1484 			for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1485 				cinval((void *) adrs);
1486 		}
1487 		sync();
1488 		/* wait a little while to see if we get a machine check */
1489 		__delay(200);
1490 	}
1491 	catch_memory_errors = 0;
1492 }
1493 
1494 unsigned long
1495 read_spr(int n)
1496 {
1497 	unsigned int instrs[2];
1498 	unsigned long (*code)(void);
1499 	unsigned long ret = -1UL;
1500 #ifdef CONFIG_PPC64
1501 	unsigned long opd[3];
1502 
1503 	opd[0] = (unsigned long)instrs;
1504 	opd[1] = 0;
1505 	opd[2] = 0;
1506 	code = (unsigned long (*)(void)) opd;
1507 #else
1508 	code = (unsigned long (*)(void)) instrs;
1509 #endif
1510 
1511 	/* mfspr r3,n; blr */
1512 	instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1513 	instrs[1] = 0x4e800020;
1514 	store_inst(instrs);
1515 	store_inst(instrs+1);
1516 
1517 	if (setjmp(bus_error_jmp) == 0) {
1518 		catch_memory_errors = 1;
1519 		sync();
1520 
1521 		ret = code();
1522 
1523 		sync();
1524 		/* wait a little while to see if we get a machine check */
1525 		__delay(200);
1526 		n = size;
1527 	}
1528 
1529 	return ret;
1530 }
1531 
1532 void
1533 write_spr(int n, unsigned long val)
1534 {
1535 	unsigned int instrs[2];
1536 	unsigned long (*code)(unsigned long);
1537 #ifdef CONFIG_PPC64
1538 	unsigned long opd[3];
1539 
1540 	opd[0] = (unsigned long)instrs;
1541 	opd[1] = 0;
1542 	opd[2] = 0;
1543 	code = (unsigned long (*)(unsigned long)) opd;
1544 #else
1545 	code = (unsigned long (*)(unsigned long)) instrs;
1546 #endif
1547 
1548 	instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1549 	instrs[1] = 0x4e800020;
1550 	store_inst(instrs);
1551 	store_inst(instrs+1);
1552 
1553 	if (setjmp(bus_error_jmp) == 0) {
1554 		catch_memory_errors = 1;
1555 		sync();
1556 
1557 		code(val);
1558 
1559 		sync();
1560 		/* wait a little while to see if we get a machine check */
1561 		__delay(200);
1562 		n = size;
1563 	}
1564 }
1565 
1566 static unsigned long regno;
1567 extern char exc_prolog;
1568 extern char dec_exc;
1569 
1570 void super_regs(void)
1571 {
1572 	int cmd;
1573 	unsigned long val;
1574 
1575 	cmd = skipbl();
1576 	if (cmd == '\n') {
1577 	        unsigned long sp, toc;
1578 		asm("mr %0,1" : "=r" (sp) :);
1579 		asm("mr %0,2" : "=r" (toc) :);
1580 
1581 		printf("msr  = "REG"  sprg0= "REG"\n",
1582 		       mfmsr(), mfspr(SPRN_SPRG0));
1583 		printf("pvr  = "REG"  sprg1= "REG"\n",
1584 		       mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
1585 		printf("dec  = "REG"  sprg2= "REG"\n",
1586 		       mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1587 		printf("sp   = "REG"  sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1588 		printf("toc  = "REG"  dar  = "REG"\n", toc, mfspr(SPRN_DAR));
1589 #ifdef CONFIG_PPC_ISERIES
1590 		if (firmware_has_feature(FW_FEATURE_ISERIES)) {
1591 			struct paca_struct *ptrPaca;
1592 			struct lppaca *ptrLpPaca;
1593 			struct ItLpRegSave *ptrLpRegSave;
1594 
1595 			/* Dump out relevant Paca data areas. */
1596 			printf("Paca: \n");
1597 			ptrPaca = get_paca();
1598 
1599 			printf("  Local Processor Control Area (LpPaca): \n");
1600 			ptrLpPaca = ptrPaca->lppaca_ptr;
1601 			printf("    Saved Srr0=%.16lx  Saved Srr1=%.16lx \n",
1602 			       ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
1603 			printf("    Saved Gpr3=%.16lx  Saved Gpr4=%.16lx \n",
1604 			       ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
1605 			printf("    Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
1606 
1607 			printf("  Local Processor Register Save Area (LpRegSave): \n");
1608 			ptrLpRegSave = ptrPaca->reg_save_ptr;
1609 			printf("    Saved Sprg0=%.16lx  Saved Sprg1=%.16lx \n",
1610 			       ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
1611 			printf("    Saved Sprg2=%.16lx  Saved Sprg3=%.16lx \n",
1612 			       ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
1613 			printf("    Saved Msr  =%.16lx  Saved Nia  =%.16lx \n",
1614 			       ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
1615 		}
1616 #endif
1617 
1618 		return;
1619 	}
1620 
1621 	scanhex(&regno);
1622 	switch (cmd) {
1623 	case 'w':
1624 		val = read_spr(regno);
1625 		scanhex(&val);
1626 		write_spr(regno, val);
1627 		/* fall through */
1628 	case 'r':
1629 		printf("spr %lx = %lx\n", regno, read_spr(regno));
1630 		break;
1631 	}
1632 	scannl();
1633 }
1634 
1635 /*
1636  * Stuff for reading and writing memory safely
1637  */
1638 int
1639 mread(unsigned long adrs, void *buf, int size)
1640 {
1641 	volatile int n;
1642 	char *p, *q;
1643 
1644 	n = 0;
1645 	if (setjmp(bus_error_jmp) == 0) {
1646 		catch_memory_errors = 1;
1647 		sync();
1648 		p = (char *)adrs;
1649 		q = (char *)buf;
1650 		switch (size) {
1651 		case 2:
1652 			*(u16 *)q = *(u16 *)p;
1653 			break;
1654 		case 4:
1655 			*(u32 *)q = *(u32 *)p;
1656 			break;
1657 		case 8:
1658 			*(u64 *)q = *(u64 *)p;
1659 			break;
1660 		default:
1661 			for( ; n < size; ++n) {
1662 				*q++ = *p++;
1663 				sync();
1664 			}
1665 		}
1666 		sync();
1667 		/* wait a little while to see if we get a machine check */
1668 		__delay(200);
1669 		n = size;
1670 	}
1671 	catch_memory_errors = 0;
1672 	return n;
1673 }
1674 
1675 int
1676 mwrite(unsigned long adrs, void *buf, int size)
1677 {
1678 	volatile int n;
1679 	char *p, *q;
1680 
1681 	n = 0;
1682 	if (setjmp(bus_error_jmp) == 0) {
1683 		catch_memory_errors = 1;
1684 		sync();
1685 		p = (char *) adrs;
1686 		q = (char *) buf;
1687 		switch (size) {
1688 		case 2:
1689 			*(u16 *)p = *(u16 *)q;
1690 			break;
1691 		case 4:
1692 			*(u32 *)p = *(u32 *)q;
1693 			break;
1694 		case 8:
1695 			*(u64 *)p = *(u64 *)q;
1696 			break;
1697 		default:
1698 			for ( ; n < size; ++n) {
1699 				*p++ = *q++;
1700 				sync();
1701 			}
1702 		}
1703 		sync();
1704 		/* wait a little while to see if we get a machine check */
1705 		__delay(200);
1706 		n = size;
1707 	} else {
1708 		printf("*** Error writing address %x\n", adrs + n);
1709 	}
1710 	catch_memory_errors = 0;
1711 	return n;
1712 }
1713 
1714 static int fault_type;
1715 static int fault_except;
1716 static char *fault_chars[] = { "--", "**", "##" };
1717 
1718 static int handle_fault(struct pt_regs *regs)
1719 {
1720 	fault_except = TRAP(regs);
1721 	switch (TRAP(regs)) {
1722 	case 0x200:
1723 		fault_type = 0;
1724 		break;
1725 	case 0x300:
1726 	case 0x380:
1727 		fault_type = 1;
1728 		break;
1729 	default:
1730 		fault_type = 2;
1731 	}
1732 
1733 	longjmp(bus_error_jmp, 1);
1734 
1735 	return 0;
1736 }
1737 
1738 #define SWAP(a, b, t)	((t) = (a), (a) = (b), (b) = (t))
1739 
1740 void
1741 byterev(unsigned char *val, int size)
1742 {
1743 	int t;
1744 
1745 	switch (size) {
1746 	case 2:
1747 		SWAP(val[0], val[1], t);
1748 		break;
1749 	case 4:
1750 		SWAP(val[0], val[3], t);
1751 		SWAP(val[1], val[2], t);
1752 		break;
1753 	case 8: /* is there really any use for this? */
1754 		SWAP(val[0], val[7], t);
1755 		SWAP(val[1], val[6], t);
1756 		SWAP(val[2], val[5], t);
1757 		SWAP(val[3], val[4], t);
1758 		break;
1759 	}
1760 }
1761 
1762 static int brev;
1763 static int mnoread;
1764 
1765 static char *memex_help_string =
1766     "Memory examine command usage:\n"
1767     "m [addr] [flags] examine/change memory\n"
1768     "  addr is optional.  will start where left off.\n"
1769     "  flags may include chars from this set:\n"
1770     "    b   modify by bytes (default)\n"
1771     "    w   modify by words (2 byte)\n"
1772     "    l   modify by longs (4 byte)\n"
1773     "    d   modify by doubleword (8 byte)\n"
1774     "    r   toggle reverse byte order mode\n"
1775     "    n   do not read memory (for i/o spaces)\n"
1776     "    .   ok to read (default)\n"
1777     "NOTE: flags are saved as defaults\n"
1778     "";
1779 
1780 static char *memex_subcmd_help_string =
1781     "Memory examine subcommands:\n"
1782     "  hexval   write this val to current location\n"
1783     "  'string' write chars from string to this location\n"
1784     "  '        increment address\n"
1785     "  ^        decrement address\n"
1786     "  /        increment addr by 0x10.  //=0x100, ///=0x1000, etc\n"
1787     "  \\        decrement addr by 0x10.  \\\\=0x100, \\\\\\=0x1000, etc\n"
1788     "  `        clear no-read flag\n"
1789     "  ;        stay at this addr\n"
1790     "  v        change to byte mode\n"
1791     "  w        change to word (2 byte) mode\n"
1792     "  l        change to long (4 byte) mode\n"
1793     "  u        change to doubleword (8 byte) mode\n"
1794     "  m addr   change current addr\n"
1795     "  n        toggle no-read flag\n"
1796     "  r        toggle byte reverse flag\n"
1797     "  < count  back up count bytes\n"
1798     "  > count  skip forward count bytes\n"
1799     "  x        exit this mode\n"
1800     "";
1801 
1802 void
1803 memex(void)
1804 {
1805 	int cmd, inc, i, nslash;
1806 	unsigned long n;
1807 	unsigned char val[16];
1808 
1809 	scanhex((void *)&adrs);
1810 	cmd = skipbl();
1811 	if (cmd == '?') {
1812 		printf(memex_help_string);
1813 		return;
1814 	} else {
1815 		termch = cmd;
1816 	}
1817 	last_cmd = "m\n";
1818 	while ((cmd = skipbl()) != '\n') {
1819 		switch( cmd ){
1820 		case 'b':	size = 1;	break;
1821 		case 'w':	size = 2;	break;
1822 		case 'l':	size = 4;	break;
1823 		case 'd':	size = 8;	break;
1824 		case 'r': 	brev = !brev;	break;
1825 		case 'n':	mnoread = 1;	break;
1826 		case '.':	mnoread = 0;	break;
1827 		}
1828 	}
1829 	if( size <= 0 )
1830 		size = 1;
1831 	else if( size > 8 )
1832 		size = 8;
1833 	for(;;){
1834 		if (!mnoread)
1835 			n = mread(adrs, val, size);
1836 		printf(REG"%c", adrs, brev? 'r': ' ');
1837 		if (!mnoread) {
1838 			if (brev)
1839 				byterev(val, size);
1840 			putchar(' ');
1841 			for (i = 0; i < n; ++i)
1842 				printf("%.2x", val[i]);
1843 			for (; i < size; ++i)
1844 				printf("%s", fault_chars[fault_type]);
1845 		}
1846 		putchar(' ');
1847 		inc = size;
1848 		nslash = 0;
1849 		for(;;){
1850 			if( scanhex(&n) ){
1851 				for (i = 0; i < size; ++i)
1852 					val[i] = n >> (i * 8);
1853 				if (!brev)
1854 					byterev(val, size);
1855 				mwrite(adrs, val, size);
1856 				inc = size;
1857 			}
1858 			cmd = skipbl();
1859 			if (cmd == '\n')
1860 				break;
1861 			inc = 0;
1862 			switch (cmd) {
1863 			case '\'':
1864 				for(;;){
1865 					n = inchar();
1866 					if( n == '\\' )
1867 						n = bsesc();
1868 					else if( n == '\'' )
1869 						break;
1870 					for (i = 0; i < size; ++i)
1871 						val[i] = n >> (i * 8);
1872 					if (!brev)
1873 						byterev(val, size);
1874 					mwrite(adrs, val, size);
1875 					adrs += size;
1876 				}
1877 				adrs -= size;
1878 				inc = size;
1879 				break;
1880 			case ',':
1881 				adrs += size;
1882 				break;
1883 			case '.':
1884 				mnoread = 0;
1885 				break;
1886 			case ';':
1887 				break;
1888 			case 'x':
1889 			case EOF:
1890 				scannl();
1891 				return;
1892 			case 'b':
1893 			case 'v':
1894 				size = 1;
1895 				break;
1896 			case 'w':
1897 				size = 2;
1898 				break;
1899 			case 'l':
1900 				size = 4;
1901 				break;
1902 			case 'u':
1903 				size = 8;
1904 				break;
1905 			case '^':
1906 				adrs -= size;
1907 				break;
1908 				break;
1909 			case '/':
1910 				if (nslash > 0)
1911 					adrs -= 1 << nslash;
1912 				else
1913 					nslash = 0;
1914 				nslash += 4;
1915 				adrs += 1 << nslash;
1916 				break;
1917 			case '\\':
1918 				if (nslash < 0)
1919 					adrs += 1 << -nslash;
1920 				else
1921 					nslash = 0;
1922 				nslash -= 4;
1923 				adrs -= 1 << -nslash;
1924 				break;
1925 			case 'm':
1926 				scanhex((void *)&adrs);
1927 				break;
1928 			case 'n':
1929 				mnoread = 1;
1930 				break;
1931 			case 'r':
1932 				brev = !brev;
1933 				break;
1934 			case '<':
1935 				n = size;
1936 				scanhex(&n);
1937 				adrs -= n;
1938 				break;
1939 			case '>':
1940 				n = size;
1941 				scanhex(&n);
1942 				adrs += n;
1943 				break;
1944 			case '?':
1945 				printf(memex_subcmd_help_string);
1946 				break;
1947 			}
1948 		}
1949 		adrs += inc;
1950 	}
1951 }
1952 
1953 int
1954 bsesc(void)
1955 {
1956 	int c;
1957 
1958 	c = inchar();
1959 	switch( c ){
1960 	case 'n':	c = '\n';	break;
1961 	case 'r':	c = '\r';	break;
1962 	case 'b':	c = '\b';	break;
1963 	case 't':	c = '\t';	break;
1964 	}
1965 	return c;
1966 }
1967 
1968 static void xmon_rawdump (unsigned long adrs, long ndump)
1969 {
1970 	long n, m, r, nr;
1971 	unsigned char temp[16];
1972 
1973 	for (n = ndump; n > 0;) {
1974 		r = n < 16? n: 16;
1975 		nr = mread(adrs, temp, r);
1976 		adrs += nr;
1977 		for (m = 0; m < r; ++m) {
1978 			if (m < nr)
1979 				printf("%.2x", temp[m]);
1980 			else
1981 				printf("%s", fault_chars[fault_type]);
1982 		}
1983 		n -= r;
1984 		if (nr < r)
1985 			break;
1986 	}
1987 	printf("\n");
1988 }
1989 
1990 #define isxdigit(c)	(('0' <= (c) && (c) <= '9') \
1991 			 || ('a' <= (c) && (c) <= 'f') \
1992 			 || ('A' <= (c) && (c) <= 'F'))
1993 void
1994 dump(void)
1995 {
1996 	int c;
1997 
1998 	c = inchar();
1999 	if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
2000 		termch = c;
2001 	scanhex((void *)&adrs);
2002 	if (termch != '\n')
2003 		termch = 0;
2004 	if (c == 'i') {
2005 		scanhex(&nidump);
2006 		if (nidump == 0)
2007 			nidump = 16;
2008 		else if (nidump > MAX_DUMP)
2009 			nidump = MAX_DUMP;
2010 		adrs += ppc_inst_dump(adrs, nidump, 1);
2011 		last_cmd = "di\n";
2012 	} else if (c == 'r') {
2013 		scanhex(&ndump);
2014 		if (ndump == 0)
2015 			ndump = 64;
2016 		xmon_rawdump(adrs, ndump);
2017 		adrs += ndump;
2018 		last_cmd = "dr\n";
2019 	} else {
2020 		scanhex(&ndump);
2021 		if (ndump == 0)
2022 			ndump = 64;
2023 		else if (ndump > MAX_DUMP)
2024 			ndump = MAX_DUMP;
2025 		prdump(adrs, ndump);
2026 		adrs += ndump;
2027 		last_cmd = "d\n";
2028 	}
2029 }
2030 
2031 void
2032 prdump(unsigned long adrs, long ndump)
2033 {
2034 	long n, m, c, r, nr;
2035 	unsigned char temp[16];
2036 
2037 	for (n = ndump; n > 0;) {
2038 		printf(REG, adrs);
2039 		putchar(' ');
2040 		r = n < 16? n: 16;
2041 		nr = mread(adrs, temp, r);
2042 		adrs += nr;
2043 		for (m = 0; m < r; ++m) {
2044 		        if ((m & (sizeof(long) - 1)) == 0 && m > 0)
2045 				putchar(' ');
2046 			if (m < nr)
2047 				printf("%.2x", temp[m]);
2048 			else
2049 				printf("%s", fault_chars[fault_type]);
2050 		}
2051 		for (; m < 16; ++m) {
2052 		        if ((m & (sizeof(long) - 1)) == 0)
2053 				putchar(' ');
2054 			printf("  ");
2055 		}
2056 		printf("  |");
2057 		for (m = 0; m < r; ++m) {
2058 			if (m < nr) {
2059 				c = temp[m];
2060 				putchar(' ' <= c && c <= '~'? c: '.');
2061 			} else
2062 				putchar(' ');
2063 		}
2064 		n -= r;
2065 		for (; m < 16; ++m)
2066 			putchar(' ');
2067 		printf("|\n");
2068 		if (nr < r)
2069 			break;
2070 	}
2071 }
2072 
2073 typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr);
2074 
2075 int
2076 generic_inst_dump(unsigned long adr, long count, int praddr,
2077 			instruction_dump_func dump_func)
2078 {
2079 	int nr, dotted;
2080 	unsigned long first_adr;
2081 	unsigned long inst, last_inst = 0;
2082 	unsigned char val[4];
2083 
2084 	dotted = 0;
2085 	for (first_adr = adr; count > 0; --count, adr += 4) {
2086 		nr = mread(adr, val, 4);
2087 		if (nr == 0) {
2088 			if (praddr) {
2089 				const char *x = fault_chars[fault_type];
2090 				printf(REG"  %s%s%s%s\n", adr, x, x, x, x);
2091 			}
2092 			break;
2093 		}
2094 		inst = GETWORD(val);
2095 		if (adr > first_adr && inst == last_inst) {
2096 			if (!dotted) {
2097 				printf(" ...\n");
2098 				dotted = 1;
2099 			}
2100 			continue;
2101 		}
2102 		dotted = 0;
2103 		last_inst = inst;
2104 		if (praddr)
2105 			printf(REG"  %.8x", adr, inst);
2106 		printf("\t");
2107 		dump_func(inst, adr);
2108 		printf("\n");
2109 	}
2110 	return adr - first_adr;
2111 }
2112 
2113 int
2114 ppc_inst_dump(unsigned long adr, long count, int praddr)
2115 {
2116 	return generic_inst_dump(adr, count, praddr, print_insn_powerpc);
2117 }
2118 
2119 void
2120 print_address(unsigned long addr)
2121 {
2122 	xmon_print_symbol(addr, "\t# ", "");
2123 }
2124 
2125 
2126 /*
2127  * Memory operations - move, set, print differences
2128  */
2129 static unsigned long mdest;		/* destination address */
2130 static unsigned long msrc;		/* source address */
2131 static unsigned long mval;		/* byte value to set memory to */
2132 static unsigned long mcount;		/* # bytes to affect */
2133 static unsigned long mdiffs;		/* max # differences to print */
2134 
2135 void
2136 memops(int cmd)
2137 {
2138 	scanhex((void *)&mdest);
2139 	if( termch != '\n' )
2140 		termch = 0;
2141 	scanhex((void *)(cmd == 's'? &mval: &msrc));
2142 	if( termch != '\n' )
2143 		termch = 0;
2144 	scanhex((void *)&mcount);
2145 	switch( cmd ){
2146 	case 'm':
2147 		memmove((void *)mdest, (void *)msrc, mcount);
2148 		break;
2149 	case 's':
2150 		memset((void *)mdest, mval, mcount);
2151 		break;
2152 	case 'd':
2153 		if( termch != '\n' )
2154 			termch = 0;
2155 		scanhex((void *)&mdiffs);
2156 		memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2157 		break;
2158 	}
2159 }
2160 
2161 void
2162 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2163 {
2164 	unsigned n, prt;
2165 
2166 	prt = 0;
2167 	for( n = nb; n > 0; --n )
2168 		if( *p1++ != *p2++ )
2169 			if( ++prt <= maxpr )
2170 				printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2171 					p1[-1], p2 - 1, p2[-1]);
2172 	if( prt > maxpr )
2173 		printf("Total of %d differences\n", prt);
2174 }
2175 
2176 static unsigned mend;
2177 static unsigned mask;
2178 
2179 void
2180 memlocate(void)
2181 {
2182 	unsigned a, n;
2183 	unsigned char val[4];
2184 
2185 	last_cmd = "ml";
2186 	scanhex((void *)&mdest);
2187 	if (termch != '\n') {
2188 		termch = 0;
2189 		scanhex((void *)&mend);
2190 		if (termch != '\n') {
2191 			termch = 0;
2192 			scanhex((void *)&mval);
2193 			mask = ~0;
2194 			if (termch != '\n') termch = 0;
2195 			scanhex((void *)&mask);
2196 		}
2197 	}
2198 	n = 0;
2199 	for (a = mdest; a < mend; a += 4) {
2200 		if (mread(a, val, 4) == 4
2201 			&& ((GETWORD(val) ^ mval) & mask) == 0) {
2202 			printf("%.16x:  %.16x\n", a, GETWORD(val));
2203 			if (++n >= 10)
2204 				break;
2205 		}
2206 	}
2207 }
2208 
2209 static unsigned long mskip = 0x1000;
2210 static unsigned long mlim = 0xffffffff;
2211 
2212 void
2213 memzcan(void)
2214 {
2215 	unsigned char v;
2216 	unsigned a;
2217 	int ok, ook;
2218 
2219 	scanhex(&mdest);
2220 	if (termch != '\n') termch = 0;
2221 	scanhex(&mskip);
2222 	if (termch != '\n') termch = 0;
2223 	scanhex(&mlim);
2224 	ook = 0;
2225 	for (a = mdest; a < mlim; a += mskip) {
2226 		ok = mread(a, &v, 1);
2227 		if (ok && !ook) {
2228 			printf("%.8x .. ", a);
2229 		} else if (!ok && ook)
2230 			printf("%.8x\n", a - mskip);
2231 		ook = ok;
2232 		if (a + mskip < a)
2233 			break;
2234 	}
2235 	if (ook)
2236 		printf("%.8x\n", a - mskip);
2237 }
2238 
2239 void proccall(void)
2240 {
2241 	unsigned long args[8];
2242 	unsigned long ret;
2243 	int i;
2244 	typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2245 			unsigned long, unsigned long, unsigned long,
2246 			unsigned long, unsigned long, unsigned long);
2247 	callfunc_t func;
2248 
2249 	if (!scanhex(&adrs))
2250 		return;
2251 	if (termch != '\n')
2252 		termch = 0;
2253 	for (i = 0; i < 8; ++i)
2254 		args[i] = 0;
2255 	for (i = 0; i < 8; ++i) {
2256 		if (!scanhex(&args[i]) || termch == '\n')
2257 			break;
2258 		termch = 0;
2259 	}
2260 	func = (callfunc_t) adrs;
2261 	ret = 0;
2262 	if (setjmp(bus_error_jmp) == 0) {
2263 		catch_memory_errors = 1;
2264 		sync();
2265 		ret = func(args[0], args[1], args[2], args[3],
2266 			   args[4], args[5], args[6], args[7]);
2267 		sync();
2268 		printf("return value is %x\n", ret);
2269 	} else {
2270 		printf("*** %x exception occurred\n", fault_except);
2271 	}
2272 	catch_memory_errors = 0;
2273 }
2274 
2275 /* Input scanning routines */
2276 int
2277 skipbl(void)
2278 {
2279 	int c;
2280 
2281 	if( termch != 0 ){
2282 		c = termch;
2283 		termch = 0;
2284 	} else
2285 		c = inchar();
2286 	while( c == ' ' || c == '\t' )
2287 		c = inchar();
2288 	return c;
2289 }
2290 
2291 #define N_PTREGS	44
2292 static char *regnames[N_PTREGS] = {
2293 	"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2294 	"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2295 	"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2296 	"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2297 	"pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2298 #ifdef CONFIG_PPC64
2299 	"softe",
2300 #else
2301 	"mq",
2302 #endif
2303 	"trap", "dar", "dsisr", "res"
2304 };
2305 
2306 int
2307 scanhex(unsigned long *vp)
2308 {
2309 	int c, d;
2310 	unsigned long v;
2311 
2312 	c = skipbl();
2313 	if (c == '%') {
2314 		/* parse register name */
2315 		char regname[8];
2316 		int i;
2317 
2318 		for (i = 0; i < sizeof(regname) - 1; ++i) {
2319 			c = inchar();
2320 			if (!isalnum(c)) {
2321 				termch = c;
2322 				break;
2323 			}
2324 			regname[i] = c;
2325 		}
2326 		regname[i] = 0;
2327 		for (i = 0; i < N_PTREGS; ++i) {
2328 			if (strcmp(regnames[i], regname) == 0) {
2329 				if (xmon_regs == NULL) {
2330 					printf("regs not available\n");
2331 					return 0;
2332 				}
2333 				*vp = ((unsigned long *)xmon_regs)[i];
2334 				return 1;
2335 			}
2336 		}
2337 		printf("invalid register name '%%%s'\n", regname);
2338 		return 0;
2339 	}
2340 
2341 	/* skip leading "0x" if any */
2342 
2343 	if (c == '0') {
2344 		c = inchar();
2345 		if (c == 'x') {
2346 			c = inchar();
2347 		} else {
2348 			d = hexdigit(c);
2349 			if (d == EOF) {
2350 				termch = c;
2351 				*vp = 0;
2352 				return 1;
2353 			}
2354 		}
2355 	} else if (c == '$') {
2356 		int i;
2357 		for (i=0; i<63; i++) {
2358 			c = inchar();
2359 			if (isspace(c)) {
2360 				termch = c;
2361 				break;
2362 			}
2363 			tmpstr[i] = c;
2364 		}
2365 		tmpstr[i++] = 0;
2366 		*vp = 0;
2367 		if (setjmp(bus_error_jmp) == 0) {
2368 			catch_memory_errors = 1;
2369 			sync();
2370 			*vp = kallsyms_lookup_name(tmpstr);
2371 			sync();
2372 		}
2373 		catch_memory_errors = 0;
2374 		if (!(*vp)) {
2375 			printf("unknown symbol '%s'\n", tmpstr);
2376 			return 0;
2377 		}
2378 		return 1;
2379 	}
2380 
2381 	d = hexdigit(c);
2382 	if (d == EOF) {
2383 		termch = c;
2384 		return 0;
2385 	}
2386 	v = 0;
2387 	do {
2388 		v = (v << 4) + d;
2389 		c = inchar();
2390 		d = hexdigit(c);
2391 	} while (d != EOF);
2392 	termch = c;
2393 	*vp = v;
2394 	return 1;
2395 }
2396 
2397 void
2398 scannl(void)
2399 {
2400 	int c;
2401 
2402 	c = termch;
2403 	termch = 0;
2404 	while( c != '\n' )
2405 		c = inchar();
2406 }
2407 
2408 int hexdigit(int c)
2409 {
2410 	if( '0' <= c && c <= '9' )
2411 		return c - '0';
2412 	if( 'A' <= c && c <= 'F' )
2413 		return c - ('A' - 10);
2414 	if( 'a' <= c && c <= 'f' )
2415 		return c - ('a' - 10);
2416 	return EOF;
2417 }
2418 
2419 void
2420 getstring(char *s, int size)
2421 {
2422 	int c;
2423 
2424 	c = skipbl();
2425 	do {
2426 		if( size > 1 ){
2427 			*s++ = c;
2428 			--size;
2429 		}
2430 		c = inchar();
2431 	} while( c != ' ' && c != '\t' && c != '\n' );
2432 	termch = c;
2433 	*s = 0;
2434 }
2435 
2436 static char line[256];
2437 static char *lineptr;
2438 
2439 void
2440 flush_input(void)
2441 {
2442 	lineptr = NULL;
2443 }
2444 
2445 int
2446 inchar(void)
2447 {
2448 	if (lineptr == NULL || *lineptr == 0) {
2449 		if (xmon_gets(line, sizeof(line)) == NULL) {
2450 			lineptr = NULL;
2451 			return EOF;
2452 		}
2453 		lineptr = line;
2454 	}
2455 	return *lineptr++;
2456 }
2457 
2458 void
2459 take_input(char *str)
2460 {
2461 	lineptr = str;
2462 }
2463 
2464 
2465 static void
2466 symbol_lookup(void)
2467 {
2468 	int type = inchar();
2469 	unsigned long addr;
2470 	static char tmp[64];
2471 
2472 	switch (type) {
2473 	case 'a':
2474 		if (scanhex(&addr))
2475 			xmon_print_symbol(addr, ": ", "\n");
2476 		termch = 0;
2477 		break;
2478 	case 's':
2479 		getstring(tmp, 64);
2480 		if (setjmp(bus_error_jmp) == 0) {
2481 			catch_memory_errors = 1;
2482 			sync();
2483 			addr = kallsyms_lookup_name(tmp);
2484 			if (addr)
2485 				printf("%s: %lx\n", tmp, addr);
2486 			else
2487 				printf("Symbol '%s' not found.\n", tmp);
2488 			sync();
2489 		}
2490 		catch_memory_errors = 0;
2491 		termch = 0;
2492 		break;
2493 	}
2494 }
2495 
2496 
2497 /* Print an address in numeric and symbolic form (if possible) */
2498 static void xmon_print_symbol(unsigned long address, const char *mid,
2499 			      const char *after)
2500 {
2501 	char *modname;
2502 	const char *name = NULL;
2503 	unsigned long offset, size;
2504 
2505 	printf(REG, address);
2506 	if (setjmp(bus_error_jmp) == 0) {
2507 		catch_memory_errors = 1;
2508 		sync();
2509 		name = kallsyms_lookup(address, &size, &offset, &modname,
2510 				       tmpstr);
2511 		sync();
2512 		/* wait a little while to see if we get a machine check */
2513 		__delay(200);
2514 	}
2515 
2516 	catch_memory_errors = 0;
2517 
2518 	if (name) {
2519 		printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2520 		if (modname)
2521 			printf(" [%s]", modname);
2522 	}
2523 	printf("%s", after);
2524 }
2525 
2526 #ifdef CONFIG_PPC64
2527 static void dump_slb(void)
2528 {
2529 	int i;
2530 	unsigned long tmp;
2531 
2532 	printf("SLB contents of cpu %x\n", smp_processor_id());
2533 
2534 	for (i = 0; i < SLB_NUM_ENTRIES; i++) {
2535 		asm volatile("slbmfee  %0,%1" : "=r" (tmp) : "r" (i));
2536 		printf("%02d %016lx ", i, tmp);
2537 
2538 		asm volatile("slbmfev  %0,%1" : "=r" (tmp) : "r" (i));
2539 		printf("%016lx\n", tmp);
2540 	}
2541 }
2542 
2543 static void dump_stab(void)
2544 {
2545 	int i;
2546 	unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2547 
2548 	printf("Segment table contents of cpu %x\n", smp_processor_id());
2549 
2550 	for (i = 0; i < PAGE_SIZE/16; i++) {
2551 		unsigned long a, b;
2552 
2553 		a = *tmp++;
2554 		b = *tmp++;
2555 
2556 		if (a || b) {
2557 			printf("%03d %016lx ", i, a);
2558 			printf("%016lx\n", b);
2559 		}
2560 	}
2561 }
2562 
2563 void dump_segments(void)
2564 {
2565 	if (cpu_has_feature(CPU_FTR_SLB))
2566 		dump_slb();
2567 	else
2568 		dump_stab();
2569 }
2570 #endif
2571 
2572 #ifdef CONFIG_PPC_STD_MMU_32
2573 void dump_segments(void)
2574 {
2575 	int i;
2576 
2577 	printf("sr0-15 =");
2578 	for (i = 0; i < 16; ++i)
2579 		printf(" %x", mfsrin(i));
2580 	printf("\n");
2581 }
2582 #endif
2583 
2584 void xmon_init(int enable)
2585 {
2586 #ifdef CONFIG_PPC_ISERIES
2587 	if (firmware_has_feature(FW_FEATURE_ISERIES))
2588 		return;
2589 #endif
2590 	if (enable) {
2591 		__debugger = xmon;
2592 		__debugger_ipi = xmon_ipi;
2593 		__debugger_bpt = xmon_bpt;
2594 		__debugger_sstep = xmon_sstep;
2595 		__debugger_iabr_match = xmon_iabr_match;
2596 		__debugger_dabr_match = xmon_dabr_match;
2597 		__debugger_fault_handler = xmon_fault_handler;
2598 	} else {
2599 		__debugger = NULL;
2600 		__debugger_ipi = NULL;
2601 		__debugger_bpt = NULL;
2602 		__debugger_sstep = NULL;
2603 		__debugger_iabr_match = NULL;
2604 		__debugger_dabr_match = NULL;
2605 		__debugger_fault_handler = NULL;
2606 	}
2607 	xmon_map_scc();
2608 }
2609 
2610 #ifdef CONFIG_MAGIC_SYSRQ
2611 static void sysrq_handle_xmon(int key, struct tty_struct *tty)
2612 {
2613 	/* ensure xmon is enabled */
2614 	xmon_init(1);
2615 	debugger(get_irq_regs());
2616 }
2617 
2618 static struct sysrq_key_op sysrq_xmon_op =
2619 {
2620 	.handler =	sysrq_handle_xmon,
2621 	.help_msg =	"Xmon",
2622 	.action_msg =	"Entering xmon",
2623 };
2624 
2625 static int __init setup_xmon_sysrq(void)
2626 {
2627 #ifdef CONFIG_PPC_ISERIES
2628 	if (firmware_has_feature(FW_FEATURE_ISERIES))
2629 		return 0;
2630 #endif
2631 	register_sysrq_key('x', &sysrq_xmon_op);
2632 	return 0;
2633 }
2634 __initcall(setup_xmon_sysrq);
2635 #endif /* CONFIG_MAGIC_SYSRQ */
2636 
2637 int __initdata xmon_early, xmon_off;
2638 
2639 static int __init early_parse_xmon(char *p)
2640 {
2641 	if (!p || strncmp(p, "early", 5) == 0) {
2642 		/* just "xmon" is equivalent to "xmon=early" */
2643 		xmon_init(1);
2644 		xmon_early = 1;
2645 	} else if (strncmp(p, "on", 2) == 0)
2646 		xmon_init(1);
2647 	else if (strncmp(p, "off", 3) == 0)
2648 		xmon_off = 1;
2649 	else if (strncmp(p, "nobt", 4) == 0)
2650 		xmon_no_auto_backtrace = 1;
2651 	else
2652 		return 1;
2653 
2654 	return 0;
2655 }
2656 early_param("xmon", early_parse_xmon);
2657 
2658 void __init xmon_setup(void)
2659 {
2660 #ifdef CONFIG_XMON_DEFAULT
2661 	if (!xmon_off)
2662 		xmon_init(1);
2663 #endif
2664 	if (xmon_early)
2665 		debugger(NULL);
2666 }
2667 
2668 #ifdef CONFIG_SPU_BASE
2669 
2670 struct spu_info {
2671 	struct spu *spu;
2672 	u64 saved_mfc_sr1_RW;
2673 	u32 saved_spu_runcntl_RW;
2674 	unsigned long dump_addr;
2675 	u8 stopped_ok;
2676 };
2677 
2678 #define XMON_NUM_SPUS	16	/* Enough for current hardware */
2679 
2680 static struct spu_info spu_info[XMON_NUM_SPUS];
2681 
2682 void xmon_register_spus(struct list_head *list)
2683 {
2684 	struct spu *spu;
2685 
2686 	list_for_each_entry(spu, list, full_list) {
2687 		if (spu->number >= XMON_NUM_SPUS) {
2688 			WARN_ON(1);
2689 			continue;
2690 		}
2691 
2692 		spu_info[spu->number].spu = spu;
2693 		spu_info[spu->number].stopped_ok = 0;
2694 		spu_info[spu->number].dump_addr = (unsigned long)
2695 				spu_info[spu->number].spu->local_store;
2696 	}
2697 }
2698 
2699 static void stop_spus(void)
2700 {
2701 	struct spu *spu;
2702 	int i;
2703 	u64 tmp;
2704 
2705 	for (i = 0; i < XMON_NUM_SPUS; i++) {
2706 		if (!spu_info[i].spu)
2707 			continue;
2708 
2709 		if (setjmp(bus_error_jmp) == 0) {
2710 			catch_memory_errors = 1;
2711 			sync();
2712 
2713 			spu = spu_info[i].spu;
2714 
2715 			spu_info[i].saved_spu_runcntl_RW =
2716 				in_be32(&spu->problem->spu_runcntl_RW);
2717 
2718 			tmp = spu_mfc_sr1_get(spu);
2719 			spu_info[i].saved_mfc_sr1_RW = tmp;
2720 
2721 			tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
2722 			spu_mfc_sr1_set(spu, tmp);
2723 
2724 			sync();
2725 			__delay(200);
2726 
2727 			spu_info[i].stopped_ok = 1;
2728 
2729 			printf("Stopped spu %.2d (was %s)\n", i,
2730 					spu_info[i].saved_spu_runcntl_RW ?
2731 					"running" : "stopped");
2732 		} else {
2733 			catch_memory_errors = 0;
2734 			printf("*** Error stopping spu %.2d\n", i);
2735 		}
2736 		catch_memory_errors = 0;
2737 	}
2738 }
2739 
2740 static void restart_spus(void)
2741 {
2742 	struct spu *spu;
2743 	int i;
2744 
2745 	for (i = 0; i < XMON_NUM_SPUS; i++) {
2746 		if (!spu_info[i].spu)
2747 			continue;
2748 
2749 		if (!spu_info[i].stopped_ok) {
2750 			printf("*** Error, spu %d was not successfully stopped"
2751 					", not restarting\n", i);
2752 			continue;
2753 		}
2754 
2755 		if (setjmp(bus_error_jmp) == 0) {
2756 			catch_memory_errors = 1;
2757 			sync();
2758 
2759 			spu = spu_info[i].spu;
2760 			spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
2761 			out_be32(&spu->problem->spu_runcntl_RW,
2762 					spu_info[i].saved_spu_runcntl_RW);
2763 
2764 			sync();
2765 			__delay(200);
2766 
2767 			printf("Restarted spu %.2d\n", i);
2768 		} else {
2769 			catch_memory_errors = 0;
2770 			printf("*** Error restarting spu %.2d\n", i);
2771 		}
2772 		catch_memory_errors = 0;
2773 	}
2774 }
2775 
2776 #define DUMP_WIDTH	23
2777 #define DUMP_VALUE(format, field, value)				\
2778 do {									\
2779 	if (setjmp(bus_error_jmp) == 0) {				\
2780 		catch_memory_errors = 1;				\
2781 		sync();							\
2782 		printf("  %-*s = "format"\n", DUMP_WIDTH,		\
2783 				#field, value);				\
2784 		sync();							\
2785 		__delay(200);						\
2786 	} else {							\
2787 		catch_memory_errors = 0;				\
2788 		printf("  %-*s = *** Error reading field.\n",		\
2789 					DUMP_WIDTH, #field);		\
2790 	}								\
2791 	catch_memory_errors = 0;					\
2792 } while (0)
2793 
2794 #define DUMP_FIELD(obj, format, field)	\
2795 	DUMP_VALUE(format, field, obj->field)
2796 
2797 static void dump_spu_fields(struct spu *spu)
2798 {
2799 	printf("Dumping spu fields at address %p:\n", spu);
2800 
2801 	DUMP_FIELD(spu, "0x%x", number);
2802 	DUMP_FIELD(spu, "%s", name);
2803 	DUMP_FIELD(spu, "0x%lx", local_store_phys);
2804 	DUMP_FIELD(spu, "0x%p", local_store);
2805 	DUMP_FIELD(spu, "0x%lx", ls_size);
2806 	DUMP_FIELD(spu, "0x%x", node);
2807 	DUMP_FIELD(spu, "0x%lx", flags);
2808 	DUMP_FIELD(spu, "0x%lx", dar);
2809 	DUMP_FIELD(spu, "0x%lx", dsisr);
2810 	DUMP_FIELD(spu, "%d", class_0_pending);
2811 	DUMP_FIELD(spu, "0x%lx", irqs[0]);
2812 	DUMP_FIELD(spu, "0x%lx", irqs[1]);
2813 	DUMP_FIELD(spu, "0x%lx", irqs[2]);
2814 	DUMP_FIELD(spu, "0x%x", slb_replace);
2815 	DUMP_FIELD(spu, "%d", pid);
2816 	DUMP_FIELD(spu, "0x%p", mm);
2817 	DUMP_FIELD(spu, "0x%p", ctx);
2818 	DUMP_FIELD(spu, "0x%p", rq);
2819 	DUMP_FIELD(spu, "0x%p", timestamp);
2820 	DUMP_FIELD(spu, "0x%lx", problem_phys);
2821 	DUMP_FIELD(spu, "0x%p", problem);
2822 	DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
2823 			in_be32(&spu->problem->spu_runcntl_RW));
2824 	DUMP_VALUE("0x%x", problem->spu_status_R,
2825 			in_be32(&spu->problem->spu_status_R));
2826 	DUMP_VALUE("0x%x", problem->spu_npc_RW,
2827 			in_be32(&spu->problem->spu_npc_RW));
2828 	DUMP_FIELD(spu, "0x%p", priv2);
2829 	DUMP_FIELD(spu, "0x%p", pdata);
2830 }
2831 
2832 int
2833 spu_inst_dump(unsigned long adr, long count, int praddr)
2834 {
2835 	return generic_inst_dump(adr, count, praddr, print_insn_spu);
2836 }
2837 
2838 static void dump_spu_ls(unsigned long num, int subcmd)
2839 {
2840 	unsigned long offset, addr, ls_addr;
2841 
2842 	if (setjmp(bus_error_jmp) == 0) {
2843 		catch_memory_errors = 1;
2844 		sync();
2845 		ls_addr = (unsigned long)spu_info[num].spu->local_store;
2846 		sync();
2847 		__delay(200);
2848 	} else {
2849 		catch_memory_errors = 0;
2850 		printf("*** Error: accessing spu info for spu %d\n", num);
2851 		return;
2852 	}
2853 	catch_memory_errors = 0;
2854 
2855 	if (scanhex(&offset))
2856 		addr = ls_addr + offset;
2857 	else
2858 		addr = spu_info[num].dump_addr;
2859 
2860 	if (addr >= ls_addr + LS_SIZE) {
2861 		printf("*** Error: address outside of local store\n");
2862 		return;
2863 	}
2864 
2865 	switch (subcmd) {
2866 	case 'i':
2867 		addr += spu_inst_dump(addr, 16, 1);
2868 		last_cmd = "sdi\n";
2869 		break;
2870 	default:
2871 		prdump(addr, 64);
2872 		addr += 64;
2873 		last_cmd = "sd\n";
2874 		break;
2875 	}
2876 
2877 	spu_info[num].dump_addr = addr;
2878 }
2879 
2880 static int do_spu_cmd(void)
2881 {
2882 	static unsigned long num = 0;
2883 	int cmd, subcmd = 0;
2884 
2885 	cmd = inchar();
2886 	switch (cmd) {
2887 	case 's':
2888 		stop_spus();
2889 		break;
2890 	case 'r':
2891 		restart_spus();
2892 		break;
2893 	case 'd':
2894 		subcmd = inchar();
2895 		if (isxdigit(subcmd) || subcmd == '\n')
2896 			termch = subcmd;
2897 	case 'f':
2898 		scanhex(&num);
2899 		if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
2900 			printf("*** Error: invalid spu number\n");
2901 			return 0;
2902 		}
2903 
2904 		switch (cmd) {
2905 		case 'f':
2906 			dump_spu_fields(spu_info[num].spu);
2907 			break;
2908 		default:
2909 			dump_spu_ls(num, subcmd);
2910 			break;
2911 		}
2912 
2913 		break;
2914 	default:
2915 		return -1;
2916 	}
2917 
2918 	return 0;
2919 }
2920 #else /* ! CONFIG_SPU_BASE */
2921 static int do_spu_cmd(void)
2922 {
2923 	return -1;
2924 }
2925 #endif
2926