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