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