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