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