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