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