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