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