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