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