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