xref: /openbmc/linux/arch/powerpc/xmon/xmon.c (revision 87c2ce3b)
1 /*
2  * Routines providing a simple monitor for use on the PowerMac.
3  *
4  * Copyright (C) 1996-2005 Paul Mackerras.
5  *
6  *      This program is free software; you can redistribute it and/or
7  *      modify it under the terms of the GNU General Public License
8  *      as published by the Free Software Foundation; either version
9  *      2 of the License, or (at your option) any later version.
10  */
11 #include <linux/config.h>
12 #include <linux/errno.h>
13 #include <linux/sched.h>
14 #include <linux/smp.h>
15 #include <linux/mm.h>
16 #include <linux/reboot.h>
17 #include <linux/delay.h>
18 #include <linux/kallsyms.h>
19 #include <linux/cpumask.h>
20 #include <linux/module.h>
21 #include <linux/sysrq.h>
22 #include <linux/interrupt.h>
23 
24 #include <asm/ptrace.h>
25 #include <asm/string.h>
26 #include <asm/prom.h>
27 #include <asm/machdep.h>
28 #include <asm/xmon.h>
29 #ifdef CONFIG_PMAC_BACKLIGHT
30 #include <asm/backlight.h>
31 #endif
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/bug.h>
40 
41 #ifdef CONFIG_PPC64
42 #include <asm/hvcall.h>
43 #include <asm/paca.h>
44 #endif
45 
46 #include "nonstdio.h"
47 
48 #define scanhex	xmon_scanhex
49 #define skipbl	xmon_skipbl
50 
51 #ifdef CONFIG_SMP
52 cpumask_t cpus_in_xmon = CPU_MASK_NONE;
53 static unsigned long xmon_taken = 1;
54 static int xmon_owner;
55 static int xmon_gate;
56 #endif /* CONFIG_SMP */
57 
58 static unsigned long in_xmon = 0;
59 
60 static unsigned long adrs;
61 static int size = 1;
62 #define MAX_DUMP (128 * 1024)
63 static unsigned long ndump = 64;
64 static unsigned long nidump = 16;
65 static unsigned long ncsum = 4096;
66 static int termch;
67 static char tmpstr[128];
68 
69 #define JMP_BUF_LEN	23
70 static long bus_error_jmp[JMP_BUF_LEN];
71 static int catch_memory_errors;
72 static long *xmon_fault_jmp[NR_CPUS];
73 #define setjmp xmon_setjmp
74 #define longjmp xmon_longjmp
75 
76 /* Breakpoint stuff */
77 struct bpt {
78 	unsigned long	address;
79 	unsigned int	instr[2];
80 	atomic_t	ref_count;
81 	int		enabled;
82 	unsigned long	pad;
83 };
84 
85 /* Bits in bpt.enabled */
86 #define BP_IABR_TE	1		/* IABR translation enabled */
87 #define BP_IABR		2
88 #define BP_TRAP		8
89 #define BP_DABR		0x10
90 
91 #define NBPTS	256
92 static struct bpt bpts[NBPTS];
93 static struct bpt dabr;
94 static struct bpt *iabr;
95 static unsigned bpinstr = 0x7fe00008;	/* trap */
96 
97 #define BP_NUM(bp)	((bp) - bpts + 1)
98 
99 /* Prototypes */
100 static int cmds(struct pt_regs *);
101 static int mread(unsigned long, void *, int);
102 static int mwrite(unsigned long, void *, int);
103 static int handle_fault(struct pt_regs *);
104 static void byterev(unsigned char *, int);
105 static void memex(void);
106 static int bsesc(void);
107 static void dump(void);
108 static void prdump(unsigned long, long);
109 static int ppc_inst_dump(unsigned long, long, int);
110 void print_address(unsigned long);
111 static void backtrace(struct pt_regs *);
112 static void excprint(struct pt_regs *);
113 static void prregs(struct pt_regs *);
114 static void memops(int);
115 static void memlocate(void);
116 static void memzcan(void);
117 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
118 int skipbl(void);
119 int scanhex(unsigned long *valp);
120 static void scannl(void);
121 static int hexdigit(int);
122 void getstring(char *, int);
123 static void flush_input(void);
124 static int inchar(void);
125 static void take_input(char *);
126 static unsigned long read_spr(int);
127 static void write_spr(int, unsigned long);
128 static void super_regs(void);
129 static void remove_bpts(void);
130 static void insert_bpts(void);
131 static void remove_cpu_bpts(void);
132 static void insert_cpu_bpts(void);
133 static struct bpt *at_breakpoint(unsigned long pc);
134 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
135 static int  do_step(struct pt_regs *);
136 static void bpt_cmds(void);
137 static void cacheflush(void);
138 static int  cpu_cmd(void);
139 static void csum(void);
140 static void bootcmds(void);
141 static void proccall(void);
142 void dump_segments(void);
143 static void symbol_lookup(void);
144 static void xmon_print_symbol(unsigned long address, const char *mid,
145 			      const char *after);
146 static const char *getvecname(unsigned long vec);
147 
148 extern int print_insn_powerpc(unsigned long, unsigned long, int);
149 
150 extern void xmon_enter(void);
151 extern void xmon_leave(void);
152 
153 extern long setjmp(long *);
154 extern void longjmp(long *, long);
155 extern void xmon_save_regs(struct pt_regs *);
156 
157 #ifdef CONFIG_PPC64
158 #define REG		"%.16lx"
159 #define REGS_PER_LINE	4
160 #define LAST_VOLATILE	13
161 #else
162 #define REG		"%.8lx"
163 #define REGS_PER_LINE	8
164 #define LAST_VOLATILE	12
165 #endif
166 
167 #define GETWORD(v)	(((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
168 
169 #define isxdigit(c)	(('0' <= (c) && (c) <= '9') \
170 			 || ('a' <= (c) && (c) <= 'f') \
171 			 || ('A' <= (c) && (c) <= 'F'))
172 #define isalnum(c)	(('0' <= (c) && (c) <= '9') \
173 			 || ('a' <= (c) && (c) <= 'z') \
174 			 || ('A' <= (c) && (c) <= 'Z'))
175 #define isspace(c)	(c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
176 
177 static char *help_string = "\
178 Commands:\n\
179   b	show breakpoints\n\
180   bd	set data breakpoint\n\
181   bi	set instruction breakpoint\n\
182   bc	clear breakpoint\n"
183 #ifdef CONFIG_SMP
184   "\
185   c	print cpus stopped in xmon\n\
186   c#	try to switch to cpu number h (in hex)\n"
187 #endif
188   "\
189   C	checksum\n\
190   d	dump bytes\n\
191   di	dump instructions\n\
192   df	dump float values\n\
193   dd	dump double values\n\
194   e	print exception information\n\
195   f	flush cache\n\
196   la	lookup symbol+offset of specified address\n\
197   ls	lookup address of specified symbol\n\
198   m	examine/change memory\n\
199   mm	move a block of memory\n\
200   ms	set a block of memory\n\
201   md	compare two blocks of memory\n\
202   ml	locate a block of memory\n\
203   mz	zero a block of memory\n\
204   mi	show information about memory allocation\n\
205   p 	call a procedure\n\
206   r	print registers\n\
207   s	single step\n\
208   S	print special registers\n\
209   t	print backtrace\n\
210   x	exit monitor and recover\n\
211   X	exit monitor and dont recover\n"
212 #ifdef CONFIG_PPC64
213 "  u	dump segment table or SLB\n"
214 #endif
215 #ifdef CONFIG_PPC_STD_MMU_32
216 "  u	dump segment registers\n"
217 #endif
218 "  ?	help\n"
219 "  zr	reboot\n\
220   zh	halt\n"
221 ;
222 
223 static struct pt_regs *xmon_regs;
224 
225 static inline void sync(void)
226 {
227 	asm volatile("sync; isync");
228 }
229 
230 static inline void store_inst(void *p)
231 {
232 	asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
233 }
234 
235 static inline void cflush(void *p)
236 {
237 	asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
238 }
239 
240 static inline void cinval(void *p)
241 {
242 	asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
243 }
244 
245 /*
246  * Disable surveillance (the service processor watchdog function)
247  * while we are in xmon.
248  * XXX we should re-enable it when we leave. :)
249  */
250 #define SURVEILLANCE_TOKEN	9000
251 
252 static inline void disable_surveillance(void)
253 {
254 #ifdef CONFIG_PPC_PSERIES
255 	/* Since this can't be a module, args should end up below 4GB. */
256 	static struct rtas_args args;
257 
258 	/*
259 	 * At this point we have got all the cpus we can into
260 	 * xmon, so there is hopefully no other cpu calling RTAS
261 	 * at the moment, even though we don't take rtas.lock.
262 	 * If we did try to take rtas.lock there would be a
263 	 * real possibility of deadlock.
264 	 */
265 	args.token = rtas_token("set-indicator");
266 	if (args.token == RTAS_UNKNOWN_SERVICE)
267 		return;
268 	args.nargs = 3;
269 	args.nret = 1;
270 	args.rets = &args.args[3];
271 	args.args[0] = SURVEILLANCE_TOKEN;
272 	args.args[1] = 0;
273 	args.args[2] = 0;
274 	enter_rtas(__pa(&args));
275 #endif /* CONFIG_PPC_PSERIES */
276 }
277 
278 #ifdef CONFIG_SMP
279 static int xmon_speaker;
280 
281 static void get_output_lock(void)
282 {
283 	int me = smp_processor_id() + 0x100;
284 	int last_speaker = 0, prev;
285 	long timeout;
286 
287 	if (xmon_speaker == me)
288 		return;
289 	for (;;) {
290 		if (xmon_speaker == 0) {
291 			last_speaker = cmpxchg(&xmon_speaker, 0, me);
292 			if (last_speaker == 0)
293 				return;
294 		}
295 		timeout = 10000000;
296 		while (xmon_speaker == last_speaker) {
297 			if (--timeout > 0)
298 				continue;
299 			/* hostile takeover */
300 			prev = cmpxchg(&xmon_speaker, last_speaker, me);
301 			if (prev == last_speaker)
302 				return;
303 			break;
304 		}
305 	}
306 }
307 
308 static void release_output_lock(void)
309 {
310 	xmon_speaker = 0;
311 }
312 #endif
313 
314 int xmon_core(struct pt_regs *regs, int fromipi)
315 {
316 	int cmd = 0;
317 	unsigned long msr;
318 	struct bpt *bp;
319 	long recurse_jmp[JMP_BUF_LEN];
320 	unsigned long offset;
321 #ifdef CONFIG_SMP
322 	int cpu;
323 	int secondary;
324 	unsigned long timeout;
325 #endif
326 
327 	msr = mfmsr();
328 	mtmsr(msr & ~MSR_EE);	/* disable interrupts */
329 
330 	bp = in_breakpoint_table(regs->nip, &offset);
331 	if (bp != NULL) {
332 		regs->nip = bp->address + offset;
333 		atomic_dec(&bp->ref_count);
334 	}
335 
336 	remove_cpu_bpts();
337 
338 #ifdef CONFIG_SMP
339 	cpu = smp_processor_id();
340 	if (cpu_isset(cpu, cpus_in_xmon)) {
341 		get_output_lock();
342 		excprint(regs);
343 		printf("cpu 0x%x: Exception %lx %s in xmon, "
344 		       "returning to main loop\n",
345 		       cpu, regs->trap, getvecname(TRAP(regs)));
346 		release_output_lock();
347 		longjmp(xmon_fault_jmp[cpu], 1);
348 	}
349 
350 	if (setjmp(recurse_jmp) != 0) {
351 		if (!in_xmon || !xmon_gate) {
352 			get_output_lock();
353 			printf("xmon: WARNING: bad recursive fault "
354 			       "on cpu 0x%x\n", cpu);
355 			release_output_lock();
356 			goto waiting;
357 		}
358 		secondary = !(xmon_taken && cpu == xmon_owner);
359 		goto cmdloop;
360 	}
361 
362 	xmon_fault_jmp[cpu] = recurse_jmp;
363 	cpu_set(cpu, cpus_in_xmon);
364 
365 	bp = NULL;
366 	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
367 		bp = at_breakpoint(regs->nip);
368 	if (bp || (regs->msr & MSR_RI) == 0)
369 		fromipi = 0;
370 
371 	if (!fromipi) {
372 		get_output_lock();
373 		excprint(regs);
374 		if (bp) {
375 			printf("cpu 0x%x stopped at breakpoint 0x%x (",
376 			       cpu, BP_NUM(bp));
377 			xmon_print_symbol(regs->nip, " ", ")\n");
378 		}
379 		if ((regs->msr & MSR_RI) == 0)
380 			printf("WARNING: exception is not recoverable, "
381 			       "can't continue\n");
382 		release_output_lock();
383 	}
384 
385  waiting:
386 	secondary = 1;
387 	while (secondary && !xmon_gate) {
388 		if (in_xmon == 0) {
389 			if (fromipi)
390 				goto leave;
391 			secondary = test_and_set_bit(0, &in_xmon);
392 		}
393 		barrier();
394 	}
395 
396 	if (!secondary && !xmon_gate) {
397 		/* we are the first cpu to come in */
398 		/* interrupt other cpu(s) */
399 		int ncpus = num_online_cpus();
400 
401 		xmon_owner = cpu;
402 		mb();
403 		if (ncpus > 1) {
404 			smp_send_debugger_break(MSG_ALL_BUT_SELF);
405 			/* wait for other cpus to come in */
406 			for (timeout = 100000000; timeout != 0; --timeout) {
407 				if (cpus_weight(cpus_in_xmon) >= ncpus)
408 					break;
409 				barrier();
410 			}
411 		}
412 		remove_bpts();
413 		disable_surveillance();
414 		/* for breakpoint or single step, print the current instr. */
415 		if (bp || TRAP(regs) == 0xd00)
416 			ppc_inst_dump(regs->nip, 1, 0);
417 		printf("enter ? for help\n");
418 		mb();
419 		xmon_gate = 1;
420 		barrier();
421 	}
422 
423  cmdloop:
424 	while (in_xmon) {
425 		if (secondary) {
426 			if (cpu == xmon_owner) {
427 				if (!test_and_set_bit(0, &xmon_taken)) {
428 					secondary = 0;
429 					continue;
430 				}
431 				/* missed it */
432 				while (cpu == xmon_owner)
433 					barrier();
434 			}
435 			barrier();
436 		} else {
437 			cmd = cmds(regs);
438 			if (cmd != 0) {
439 				/* exiting xmon */
440 				insert_bpts();
441 				xmon_gate = 0;
442 				wmb();
443 				in_xmon = 0;
444 				break;
445 			}
446 			/* have switched to some other cpu */
447 			secondary = 1;
448 		}
449 	}
450  leave:
451 	cpu_clear(cpu, cpus_in_xmon);
452 	xmon_fault_jmp[cpu] = NULL;
453 #else
454 	/* UP is simple... */
455 	if (in_xmon) {
456 		printf("Exception %lx %s in xmon, returning to main loop\n",
457 		       regs->trap, getvecname(TRAP(regs)));
458 		longjmp(xmon_fault_jmp[0], 1);
459 	}
460 	if (setjmp(recurse_jmp) == 0) {
461 		xmon_fault_jmp[0] = recurse_jmp;
462 		in_xmon = 1;
463 
464 		excprint(regs);
465 		bp = at_breakpoint(regs->nip);
466 		if (bp) {
467 			printf("Stopped at breakpoint %x (", BP_NUM(bp));
468 			xmon_print_symbol(regs->nip, " ", ")\n");
469 		}
470 		if ((regs->msr & MSR_RI) == 0)
471 			printf("WARNING: exception is not recoverable, "
472 			       "can't continue\n");
473 		remove_bpts();
474 		disable_surveillance();
475 		/* for breakpoint or single step, print the current instr. */
476 		if (bp || TRAP(regs) == 0xd00)
477 			ppc_inst_dump(regs->nip, 1, 0);
478 		printf("enter ? for help\n");
479 	}
480 
481 	cmd = cmds(regs);
482 
483 	insert_bpts();
484 	in_xmon = 0;
485 #endif
486 
487 	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
488 		bp = at_breakpoint(regs->nip);
489 		if (bp != NULL) {
490 			int stepped = emulate_step(regs, bp->instr[0]);
491 			if (stepped == 0) {
492 				regs->nip = (unsigned long) &bp->instr[0];
493 				atomic_inc(&bp->ref_count);
494 			} else if (stepped < 0) {
495 				printf("Couldn't single-step %s instruction\n",
496 				    (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
497 			}
498 		}
499 	}
500 
501 	insert_cpu_bpts();
502 
503 	mtmsr(msr);		/* restore interrupt enable */
504 
505 	return cmd != 'X';
506 }
507 
508 int xmon(struct pt_regs *excp)
509 {
510 	struct pt_regs regs;
511 
512 	if (excp == NULL) {
513 		xmon_save_regs(&regs);
514 		excp = &regs;
515 	}
516 	return xmon_core(excp, 0);
517 }
518 EXPORT_SYMBOL(xmon);
519 
520 irqreturn_t
521 xmon_irq(int irq, void *d, struct pt_regs *regs)
522 {
523 	unsigned long flags;
524 	local_irq_save(flags);
525 	printf("Keyboard interrupt\n");
526 	xmon(regs);
527 	local_irq_restore(flags);
528 	return IRQ_HANDLED;
529 }
530 
531 int xmon_bpt(struct pt_regs *regs)
532 {
533 	struct bpt *bp;
534 	unsigned long offset;
535 
536 	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
537 		return 0;
538 
539 	/* Are we at the trap at bp->instr[1] for some bp? */
540 	bp = in_breakpoint_table(regs->nip, &offset);
541 	if (bp != NULL && offset == 4) {
542 		regs->nip = bp->address + 4;
543 		atomic_dec(&bp->ref_count);
544 		return 1;
545 	}
546 
547 	/* Are we at a breakpoint? */
548 	bp = at_breakpoint(regs->nip);
549 	if (!bp)
550 		return 0;
551 
552 	xmon_core(regs, 0);
553 
554 	return 1;
555 }
556 
557 int xmon_sstep(struct pt_regs *regs)
558 {
559 	if (user_mode(regs))
560 		return 0;
561 	xmon_core(regs, 0);
562 	return 1;
563 }
564 
565 int xmon_dabr_match(struct pt_regs *regs)
566 {
567 	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
568 		return 0;
569 	if (dabr.enabled == 0)
570 		return 0;
571 	xmon_core(regs, 0);
572 	return 1;
573 }
574 
575 int xmon_iabr_match(struct pt_regs *regs)
576 {
577 	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
578 		return 0;
579 	if (iabr == 0)
580 		return 0;
581 	xmon_core(regs, 0);
582 	return 1;
583 }
584 
585 int xmon_ipi(struct pt_regs *regs)
586 {
587 #ifdef CONFIG_SMP
588 	if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
589 		xmon_core(regs, 1);
590 #endif
591 	return 0;
592 }
593 
594 int xmon_fault_handler(struct pt_regs *regs)
595 {
596 	struct bpt *bp;
597 	unsigned long offset;
598 
599 	if (in_xmon && catch_memory_errors)
600 		handle_fault(regs);	/* doesn't return */
601 
602 	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
603 		bp = in_breakpoint_table(regs->nip, &offset);
604 		if (bp != NULL) {
605 			regs->nip = bp->address + offset;
606 			atomic_dec(&bp->ref_count);
607 		}
608 	}
609 
610 	return 0;
611 }
612 
613 static struct bpt *at_breakpoint(unsigned long pc)
614 {
615 	int i;
616 	struct bpt *bp;
617 
618 	bp = bpts;
619 	for (i = 0; i < NBPTS; ++i, ++bp)
620 		if (bp->enabled && pc == bp->address)
621 			return bp;
622 	return NULL;
623 }
624 
625 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
626 {
627 	unsigned long off;
628 
629 	off = nip - (unsigned long) bpts;
630 	if (off >= sizeof(bpts))
631 		return NULL;
632 	off %= sizeof(struct bpt);
633 	if (off != offsetof(struct bpt, instr[0])
634 	    && off != offsetof(struct bpt, instr[1]))
635 		return NULL;
636 	*offp = off - offsetof(struct bpt, instr[0]);
637 	return (struct bpt *) (nip - off);
638 }
639 
640 static struct bpt *new_breakpoint(unsigned long a)
641 {
642 	struct bpt *bp;
643 
644 	a &= ~3UL;
645 	bp = at_breakpoint(a);
646 	if (bp)
647 		return bp;
648 
649 	for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
650 		if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
651 			bp->address = a;
652 			bp->instr[1] = bpinstr;
653 			store_inst(&bp->instr[1]);
654 			return bp;
655 		}
656 	}
657 
658 	printf("Sorry, no free breakpoints.  Please clear one first.\n");
659 	return NULL;
660 }
661 
662 static void insert_bpts(void)
663 {
664 	int i;
665 	struct bpt *bp;
666 
667 	bp = bpts;
668 	for (i = 0; i < NBPTS; ++i, ++bp) {
669 		if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
670 			continue;
671 		if (mread(bp->address, &bp->instr[0], 4) != 4) {
672 			printf("Couldn't read instruction at %lx, "
673 			       "disabling breakpoint there\n", bp->address);
674 			bp->enabled = 0;
675 			continue;
676 		}
677 		if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
678 			printf("Breakpoint at %lx is on an mtmsrd or rfid "
679 			       "instruction, disabling it\n", bp->address);
680 			bp->enabled = 0;
681 			continue;
682 		}
683 		store_inst(&bp->instr[0]);
684 		if (bp->enabled & BP_IABR)
685 			continue;
686 		if (mwrite(bp->address, &bpinstr, 4) != 4) {
687 			printf("Couldn't write instruction at %lx, "
688 			       "disabling breakpoint there\n", bp->address);
689 			bp->enabled &= ~BP_TRAP;
690 			continue;
691 		}
692 		store_inst((void *)bp->address);
693 	}
694 }
695 
696 static void insert_cpu_bpts(void)
697 {
698 	if (dabr.enabled)
699 		set_dabr(dabr.address | (dabr.enabled & 7));
700 	if (iabr && cpu_has_feature(CPU_FTR_IABR))
701 		mtspr(SPRN_IABR, iabr->address
702 			 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
703 }
704 
705 static void remove_bpts(void)
706 {
707 	int i;
708 	struct bpt *bp;
709 	unsigned instr;
710 
711 	bp = bpts;
712 	for (i = 0; i < NBPTS; ++i, ++bp) {
713 		if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
714 			continue;
715 		if (mread(bp->address, &instr, 4) == 4
716 		    && instr == bpinstr
717 		    && mwrite(bp->address, &bp->instr, 4) != 4)
718 			printf("Couldn't remove breakpoint at %lx\n",
719 			       bp->address);
720 		else
721 			store_inst((void *)bp->address);
722 	}
723 }
724 
725 static void remove_cpu_bpts(void)
726 {
727 	set_dabr(0);
728 	if (cpu_has_feature(CPU_FTR_IABR))
729 		mtspr(SPRN_IABR, 0);
730 }
731 
732 /* Command interpreting routine */
733 static char *last_cmd;
734 
735 static int
736 cmds(struct pt_regs *excp)
737 {
738 	int cmd = 0;
739 
740 	last_cmd = NULL;
741 	xmon_regs = excp;
742 	for(;;) {
743 #ifdef CONFIG_SMP
744 		printf("%x:", smp_processor_id());
745 #endif /* CONFIG_SMP */
746 		printf("mon> ");
747 		flush_input();
748 		termch = 0;
749 		cmd = skipbl();
750 		if( cmd == '\n' ) {
751 			if (last_cmd == NULL)
752 				continue;
753 			take_input(last_cmd);
754 			last_cmd = NULL;
755 			cmd = inchar();
756 		}
757 		switch (cmd) {
758 		case 'm':
759 			cmd = inchar();
760 			switch (cmd) {
761 			case 'm':
762 			case 's':
763 			case 'd':
764 				memops(cmd);
765 				break;
766 			case 'l':
767 				memlocate();
768 				break;
769 			case 'z':
770 				memzcan();
771 				break;
772 			case 'i':
773 				show_mem();
774 				break;
775 			default:
776 				termch = cmd;
777 				memex();
778 			}
779 			break;
780 		case 'd':
781 			dump();
782 			break;
783 		case 'l':
784 			symbol_lookup();
785 			break;
786 		case 'r':
787 			prregs(excp);	/* print regs */
788 			break;
789 		case 'e':
790 			excprint(excp);
791 			break;
792 		case 'S':
793 			super_regs();
794 			break;
795 		case 't':
796 			backtrace(excp);
797 			break;
798 		case 'f':
799 			cacheflush();
800 			break;
801 		case 's':
802 			if (do_step(excp))
803 				return cmd;
804 			break;
805 		case 'x':
806 		case 'X':
807 			return cmd;
808 		case EOF:
809 			printf(" <no input ...>\n");
810 			mdelay(2000);
811 			return cmd;
812 		case '?':
813 			printf(help_string);
814 			break;
815 		case 'b':
816 			bpt_cmds();
817 			break;
818 		case 'C':
819 			csum();
820 			break;
821 		case 'c':
822 			if (cpu_cmd())
823 				return 0;
824 			break;
825 		case 'z':
826 			bootcmds();
827 			break;
828 		case 'p':
829 			proccall();
830 			break;
831 #ifdef CONFIG_PPC_STD_MMU
832 		case 'u':
833 			dump_segments();
834 			break;
835 #endif
836 		default:
837 			printf("Unrecognized command: ");
838 		        do {
839 				if (' ' < cmd && cmd <= '~')
840 					putchar(cmd);
841 				else
842 					printf("\\x%x", cmd);
843 				cmd = inchar();
844 		        } while (cmd != '\n');
845 			printf(" (type ? for help)\n");
846 			break;
847 		}
848 	}
849 }
850 
851 /*
852  * Step a single instruction.
853  * Some instructions we emulate, others we execute with MSR_SE set.
854  */
855 static int do_step(struct pt_regs *regs)
856 {
857 	unsigned int instr;
858 	int stepped;
859 
860 	/* check we are in 64-bit kernel mode, translation enabled */
861 	if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
862 		if (mread(regs->nip, &instr, 4) == 4) {
863 			stepped = emulate_step(regs, instr);
864 			if (stepped < 0) {
865 				printf("Couldn't single-step %s instruction\n",
866 				       (IS_RFID(instr)? "rfid": "mtmsrd"));
867 				return 0;
868 			}
869 			if (stepped > 0) {
870 				regs->trap = 0xd00 | (regs->trap & 1);
871 				printf("stepped to ");
872 				xmon_print_symbol(regs->nip, " ", "\n");
873 				ppc_inst_dump(regs->nip, 1, 0);
874 				return 0;
875 			}
876 		}
877 	}
878 	regs->msr |= MSR_SE;
879 	return 1;
880 }
881 
882 static void bootcmds(void)
883 {
884 	int cmd;
885 
886 	cmd = inchar();
887 	if (cmd == 'r')
888 		ppc_md.restart(NULL);
889 	else if (cmd == 'h')
890 		ppc_md.halt();
891 	else if (cmd == 'p')
892 		ppc_md.power_off();
893 }
894 
895 static int cpu_cmd(void)
896 {
897 #ifdef CONFIG_SMP
898 	unsigned long cpu;
899 	int timeout;
900 	int count;
901 
902 	if (!scanhex(&cpu)) {
903 		/* print cpus waiting or in xmon */
904 		printf("cpus stopped:");
905 		count = 0;
906 		for (cpu = 0; cpu < NR_CPUS; ++cpu) {
907 			if (cpu_isset(cpu, cpus_in_xmon)) {
908 				if (count == 0)
909 					printf(" %x", cpu);
910 				++count;
911 			} else {
912 				if (count > 1)
913 					printf("-%x", cpu - 1);
914 				count = 0;
915 			}
916 		}
917 		if (count > 1)
918 			printf("-%x", NR_CPUS - 1);
919 		printf("\n");
920 		return 0;
921 	}
922 	/* try to switch to cpu specified */
923 	if (!cpu_isset(cpu, cpus_in_xmon)) {
924 		printf("cpu 0x%x isn't in xmon\n", cpu);
925 		return 0;
926 	}
927 	xmon_taken = 0;
928 	mb();
929 	xmon_owner = cpu;
930 	timeout = 10000000;
931 	while (!xmon_taken) {
932 		if (--timeout == 0) {
933 			if (test_and_set_bit(0, &xmon_taken))
934 				break;
935 			/* take control back */
936 			mb();
937 			xmon_owner = smp_processor_id();
938 			printf("cpu %u didn't take control\n", cpu);
939 			return 0;
940 		}
941 		barrier();
942 	}
943 	return 1;
944 #else
945 	return 0;
946 #endif /* CONFIG_SMP */
947 }
948 
949 static unsigned short fcstab[256] = {
950 	0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
951 	0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
952 	0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
953 	0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
954 	0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
955 	0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
956 	0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
957 	0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
958 	0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
959 	0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
960 	0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
961 	0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
962 	0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
963 	0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
964 	0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
965 	0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
966 	0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
967 	0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
968 	0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
969 	0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
970 	0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
971 	0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
972 	0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
973 	0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
974 	0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
975 	0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
976 	0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
977 	0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
978 	0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
979 	0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
980 	0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
981 	0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
982 };
983 
984 #define FCS(fcs, c)	(((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
985 
986 static void
987 csum(void)
988 {
989 	unsigned int i;
990 	unsigned short fcs;
991 	unsigned char v;
992 
993 	if (!scanhex(&adrs))
994 		return;
995 	if (!scanhex(&ncsum))
996 		return;
997 	fcs = 0xffff;
998 	for (i = 0; i < ncsum; ++i) {
999 		if (mread(adrs+i, &v, 1) == 0) {
1000 			printf("csum stopped at %x\n", adrs+i);
1001 			break;
1002 		}
1003 		fcs = FCS(fcs, v);
1004 	}
1005 	printf("%x\n", fcs);
1006 }
1007 
1008 /*
1009  * Check if this is a suitable place to put a breakpoint.
1010  */
1011 static long check_bp_loc(unsigned long addr)
1012 {
1013 	unsigned int instr;
1014 
1015 	addr &= ~3;
1016 	if (!is_kernel_addr(addr)) {
1017 		printf("Breakpoints may only be placed at kernel addresses\n");
1018 		return 0;
1019 	}
1020 	if (!mread(addr, &instr, sizeof(instr))) {
1021 		printf("Can't read instruction at address %lx\n", addr);
1022 		return 0;
1023 	}
1024 	if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1025 		printf("Breakpoints may not be placed on mtmsrd or rfid "
1026 		       "instructions\n");
1027 		return 0;
1028 	}
1029 	return 1;
1030 }
1031 
1032 static char *breakpoint_help_string =
1033     "Breakpoint command usage:\n"
1034     "b                show breakpoints\n"
1035     "b <addr> [cnt]   set breakpoint at given instr addr\n"
1036     "bc               clear all breakpoints\n"
1037     "bc <n/addr>      clear breakpoint number n or at addr\n"
1038     "bi <addr> [cnt]  set hardware instr breakpoint (POWER3/RS64 only)\n"
1039     "bd <addr> [cnt]  set hardware data breakpoint\n"
1040     "";
1041 
1042 static void
1043 bpt_cmds(void)
1044 {
1045 	int cmd;
1046 	unsigned long a;
1047 	int mode, i;
1048 	struct bpt *bp;
1049 	const char badaddr[] = "Only kernel addresses are permitted "
1050 		"for breakpoints\n";
1051 
1052 	cmd = inchar();
1053 	switch (cmd) {
1054 #ifndef CONFIG_8xx
1055 	case 'd':	/* bd - hardware data breakpoint */
1056 		mode = 7;
1057 		cmd = inchar();
1058 		if (cmd == 'r')
1059 			mode = 5;
1060 		else if (cmd == 'w')
1061 			mode = 6;
1062 		else
1063 			termch = cmd;
1064 		dabr.address = 0;
1065 		dabr.enabled = 0;
1066 		if (scanhex(&dabr.address)) {
1067 			if (!is_kernel_addr(dabr.address)) {
1068 				printf(badaddr);
1069 				break;
1070 			}
1071 			dabr.address &= ~7;
1072 			dabr.enabled = mode | BP_DABR;
1073 		}
1074 		break;
1075 
1076 	case 'i':	/* bi - hardware instr breakpoint */
1077 		if (!cpu_has_feature(CPU_FTR_IABR)) {
1078 			printf("Hardware instruction breakpoint "
1079 			       "not supported on this cpu\n");
1080 			break;
1081 		}
1082 		if (iabr) {
1083 			iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1084 			iabr = NULL;
1085 		}
1086 		if (!scanhex(&a))
1087 			break;
1088 		if (!check_bp_loc(a))
1089 			break;
1090 		bp = new_breakpoint(a);
1091 		if (bp != NULL) {
1092 			bp->enabled |= BP_IABR | BP_IABR_TE;
1093 			iabr = bp;
1094 		}
1095 		break;
1096 #endif
1097 
1098 	case 'c':
1099 		if (!scanhex(&a)) {
1100 			/* clear all breakpoints */
1101 			for (i = 0; i < NBPTS; ++i)
1102 				bpts[i].enabled = 0;
1103 			iabr = NULL;
1104 			dabr.enabled = 0;
1105 			printf("All breakpoints cleared\n");
1106 			break;
1107 		}
1108 
1109 		if (a <= NBPTS && a >= 1) {
1110 			/* assume a breakpoint number */
1111 			bp = &bpts[a-1];	/* bp nums are 1 based */
1112 		} else {
1113 			/* assume a breakpoint address */
1114 			bp = at_breakpoint(a);
1115 			if (bp == 0) {
1116 				printf("No breakpoint at %x\n", a);
1117 				break;
1118 			}
1119 		}
1120 
1121 		printf("Cleared breakpoint %x (", BP_NUM(bp));
1122 		xmon_print_symbol(bp->address, " ", ")\n");
1123 		bp->enabled = 0;
1124 		break;
1125 
1126 	default:
1127 		termch = cmd;
1128 	        cmd = skipbl();
1129 		if (cmd == '?') {
1130 			printf(breakpoint_help_string);
1131 			break;
1132 		}
1133 		termch = cmd;
1134 		if (!scanhex(&a)) {
1135 			/* print all breakpoints */
1136 			printf("   type            address\n");
1137 			if (dabr.enabled) {
1138 				printf("   data   "REG"  [", dabr.address);
1139 				if (dabr.enabled & 1)
1140 					printf("r");
1141 				if (dabr.enabled & 2)
1142 					printf("w");
1143 				printf("]\n");
1144 			}
1145 			for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1146 				if (!bp->enabled)
1147 					continue;
1148 				printf("%2x %s   ", BP_NUM(bp),
1149 				    (bp->enabled & BP_IABR)? "inst": "trap");
1150 				xmon_print_symbol(bp->address, "  ", "\n");
1151 			}
1152 			break;
1153 		}
1154 
1155 		if (!check_bp_loc(a))
1156 			break;
1157 		bp = new_breakpoint(a);
1158 		if (bp != NULL)
1159 			bp->enabled |= BP_TRAP;
1160 		break;
1161 	}
1162 }
1163 
1164 /* Very cheap human name for vector lookup. */
1165 static
1166 const char *getvecname(unsigned long vec)
1167 {
1168 	char *ret;
1169 
1170 	switch (vec) {
1171 	case 0x100:	ret = "(System Reset)"; break;
1172 	case 0x200:	ret = "(Machine Check)"; break;
1173 	case 0x300:	ret = "(Data Access)"; break;
1174 	case 0x380:	ret = "(Data SLB Access)"; break;
1175 	case 0x400:	ret = "(Instruction Access)"; break;
1176 	case 0x480:	ret = "(Instruction SLB Access)"; break;
1177 	case 0x500:	ret = "(Hardware Interrupt)"; break;
1178 	case 0x600:	ret = "(Alignment)"; break;
1179 	case 0x700:	ret = "(Program Check)"; break;
1180 	case 0x800:	ret = "(FPU Unavailable)"; break;
1181 	case 0x900:	ret = "(Decrementer)"; break;
1182 	case 0xc00:	ret = "(System Call)"; break;
1183 	case 0xd00:	ret = "(Single Step)"; break;
1184 	case 0xf00:	ret = "(Performance Monitor)"; break;
1185 	case 0xf20:	ret = "(Altivec Unavailable)"; break;
1186 	case 0x1300:	ret = "(Instruction Breakpoint)"; break;
1187 	default: ret = "";
1188 	}
1189 	return ret;
1190 }
1191 
1192 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1193 				unsigned long *endp)
1194 {
1195 	unsigned long size, offset;
1196 	const char *name;
1197 	char *modname;
1198 
1199 	*startp = *endp = 0;
1200 	if (pc == 0)
1201 		return;
1202 	if (setjmp(bus_error_jmp) == 0) {
1203 		catch_memory_errors = 1;
1204 		sync();
1205 		name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr);
1206 		if (name != NULL) {
1207 			*startp = pc - offset;
1208 			*endp = pc - offset + size;
1209 		}
1210 		sync();
1211 	}
1212 	catch_memory_errors = 0;
1213 }
1214 
1215 static int xmon_depth_to_print = 64;
1216 
1217 #ifdef CONFIG_PPC64
1218 #define LRSAVE_OFFSET		0x10
1219 #define REG_FRAME_MARKER	0x7265677368657265ul	/* "regshere" */
1220 #define MARKER_OFFSET		0x60
1221 #define REGS_OFFSET		0x70
1222 #else
1223 #define LRSAVE_OFFSET		4
1224 #define REG_FRAME_MARKER	0x72656773
1225 #define MARKER_OFFSET		8
1226 #define REGS_OFFSET		16
1227 #endif
1228 
1229 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1230 			    unsigned long pc)
1231 {
1232 	unsigned long ip;
1233 	unsigned long newsp;
1234 	unsigned long marker;
1235 	int count = 0;
1236 	struct pt_regs regs;
1237 
1238 	do {
1239 		if (sp < PAGE_OFFSET) {
1240 			if (sp != 0)
1241 				printf("SP (%lx) is in userspace\n", sp);
1242 			break;
1243 		}
1244 
1245 		if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1246 		    || !mread(sp, &newsp, sizeof(unsigned long))) {
1247 			printf("Couldn't read stack frame at %lx\n", sp);
1248 			break;
1249 		}
1250 
1251 		/*
1252 		 * For the first stack frame, try to work out if
1253 		 * LR and/or the saved LR value in the bottommost
1254 		 * stack frame are valid.
1255 		 */
1256 		if ((pc | lr) != 0) {
1257 			unsigned long fnstart, fnend;
1258 			unsigned long nextip;
1259 			int printip = 1;
1260 
1261 			get_function_bounds(pc, &fnstart, &fnend);
1262 			nextip = 0;
1263 			if (newsp > sp)
1264 				mread(newsp + LRSAVE_OFFSET, &nextip,
1265 				      sizeof(unsigned long));
1266 			if (lr == ip) {
1267 				if (lr < PAGE_OFFSET
1268 				    || (fnstart <= lr && lr < fnend))
1269 					printip = 0;
1270 			} else if (lr == nextip) {
1271 				printip = 0;
1272 			} else if (lr >= PAGE_OFFSET
1273 				   && !(fnstart <= lr && lr < fnend)) {
1274 				printf("[link register   ] ");
1275 				xmon_print_symbol(lr, " ", "\n");
1276 			}
1277 			if (printip) {
1278 				printf("["REG"] ", sp);
1279 				xmon_print_symbol(ip, " ", " (unreliable)\n");
1280 			}
1281 			pc = lr = 0;
1282 
1283 		} else {
1284 			printf("["REG"] ", sp);
1285 			xmon_print_symbol(ip, " ", "\n");
1286 		}
1287 
1288 		/* Look for "regshere" marker to see if this is
1289 		   an exception frame. */
1290 		if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1291 		    && marker == REG_FRAME_MARKER) {
1292 			if (mread(sp + REGS_OFFSET, &regs, sizeof(regs))
1293 			    != sizeof(regs)) {
1294 				printf("Couldn't read registers at %lx\n",
1295 				       sp + REGS_OFFSET);
1296 				break;
1297 			}
1298                         printf("--- Exception: %lx %s at ", regs.trap,
1299 			       getvecname(TRAP(&regs)));
1300 			pc = regs.nip;
1301 			lr = regs.link;
1302 			xmon_print_symbol(pc, " ", "\n");
1303 		}
1304 
1305 		if (newsp == 0)
1306 			break;
1307 
1308 		sp = newsp;
1309 	} while (count++ < xmon_depth_to_print);
1310 }
1311 
1312 static void backtrace(struct pt_regs *excp)
1313 {
1314 	unsigned long sp;
1315 
1316 	if (scanhex(&sp))
1317 		xmon_show_stack(sp, 0, 0);
1318 	else
1319 		xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1320 	scannl();
1321 }
1322 
1323 static void print_bug_trap(struct pt_regs *regs)
1324 {
1325 	struct bug_entry *bug;
1326 	unsigned long addr;
1327 
1328 	if (regs->msr & MSR_PR)
1329 		return;		/* not in kernel */
1330 	addr = regs->nip;	/* address of trap instruction */
1331 	if (addr < PAGE_OFFSET)
1332 		return;
1333 	bug = find_bug(regs->nip);
1334 	if (bug == NULL)
1335 		return;
1336 	if (bug->line & BUG_WARNING_TRAP)
1337 		return;
1338 
1339 	printf("kernel BUG in %s at %s:%d!\n",
1340 	       bug->function, bug->file, (unsigned int)bug->line);
1341 }
1342 
1343 void excprint(struct pt_regs *fp)
1344 {
1345 	unsigned long trap;
1346 
1347 #ifdef CONFIG_SMP
1348 	printf("cpu 0x%x: ", smp_processor_id());
1349 #endif /* CONFIG_SMP */
1350 
1351 	trap = TRAP(fp);
1352 	printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1353 	printf("    pc: ");
1354 	xmon_print_symbol(fp->nip, ": ", "\n");
1355 
1356 	printf("    lr: ", fp->link);
1357 	xmon_print_symbol(fp->link, ": ", "\n");
1358 
1359 	printf("    sp: %lx\n", fp->gpr[1]);
1360 	printf("   msr: %lx\n", fp->msr);
1361 
1362 	if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1363 		printf("   dar: %lx\n", fp->dar);
1364 		if (trap != 0x380)
1365 			printf(" dsisr: %lx\n", fp->dsisr);
1366 	}
1367 
1368 	printf("  current = 0x%lx\n", current);
1369 #ifdef CONFIG_PPC64
1370 	printf("  paca    = 0x%lx\n", get_paca());
1371 #endif
1372 	if (current) {
1373 		printf("    pid   = %ld, comm = %s\n",
1374 		       current->pid, current->comm);
1375 	}
1376 
1377 	if (trap == 0x700)
1378 		print_bug_trap(fp);
1379 }
1380 
1381 void prregs(struct pt_regs *fp)
1382 {
1383 	int n, trap;
1384 	unsigned long base;
1385 	struct pt_regs regs;
1386 
1387 	if (scanhex(&base)) {
1388 		if (setjmp(bus_error_jmp) == 0) {
1389 			catch_memory_errors = 1;
1390 			sync();
1391 			regs = *(struct pt_regs *)base;
1392 			sync();
1393 			__delay(200);
1394 		} else {
1395 			catch_memory_errors = 0;
1396 			printf("*** Error reading registers from "REG"\n",
1397 			       base);
1398 			return;
1399 		}
1400 		catch_memory_errors = 0;
1401 		fp = &regs;
1402 	}
1403 
1404 #ifdef CONFIG_PPC64
1405 	if (FULL_REGS(fp)) {
1406 		for (n = 0; n < 16; ++n)
1407 			printf("R%.2ld = "REG"   R%.2ld = "REG"\n",
1408 			       n, fp->gpr[n], n+16, fp->gpr[n+16]);
1409 	} else {
1410 		for (n = 0; n < 7; ++n)
1411 			printf("R%.2ld = "REG"   R%.2ld = "REG"\n",
1412 			       n, fp->gpr[n], n+7, fp->gpr[n+7]);
1413 	}
1414 #else
1415 	for (n = 0; n < 32; ++n) {
1416 		printf("R%.2d = %.8x%s", n, fp->gpr[n],
1417 		       (n & 3) == 3? "\n": "   ");
1418 		if (n == 12 && !FULL_REGS(fp)) {
1419 			printf("\n");
1420 			break;
1421 		}
1422 	}
1423 #endif
1424 	printf("pc  = ");
1425 	xmon_print_symbol(fp->nip, " ", "\n");
1426 	printf("lr  = ");
1427 	xmon_print_symbol(fp->link, " ", "\n");
1428 	printf("msr = "REG"   cr  = %.8lx\n", fp->msr, fp->ccr);
1429 	printf("ctr = "REG"   xer = "REG"   trap = %4lx\n",
1430 	       fp->ctr, fp->xer, fp->trap);
1431 	trap = TRAP(fp);
1432 	if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1433 		printf("dar = "REG"   dsisr = %.8lx\n", fp->dar, fp->dsisr);
1434 }
1435 
1436 void cacheflush(void)
1437 {
1438 	int cmd;
1439 	unsigned long nflush;
1440 
1441 	cmd = inchar();
1442 	if (cmd != 'i')
1443 		termch = cmd;
1444 	scanhex((void *)&adrs);
1445 	if (termch != '\n')
1446 		termch = 0;
1447 	nflush = 1;
1448 	scanhex(&nflush);
1449 	nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1450 	if (setjmp(bus_error_jmp) == 0) {
1451 		catch_memory_errors = 1;
1452 		sync();
1453 
1454 		if (cmd != 'i') {
1455 			for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1456 				cflush((void *) adrs);
1457 		} else {
1458 			for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1459 				cinval((void *) adrs);
1460 		}
1461 		sync();
1462 		/* wait a little while to see if we get a machine check */
1463 		__delay(200);
1464 	}
1465 	catch_memory_errors = 0;
1466 }
1467 
1468 unsigned long
1469 read_spr(int n)
1470 {
1471 	unsigned int instrs[2];
1472 	unsigned long (*code)(void);
1473 	unsigned long ret = -1UL;
1474 #ifdef CONFIG_PPC64
1475 	unsigned long opd[3];
1476 
1477 	opd[0] = (unsigned long)instrs;
1478 	opd[1] = 0;
1479 	opd[2] = 0;
1480 	code = (unsigned long (*)(void)) opd;
1481 #else
1482 	code = (unsigned long (*)(void)) instrs;
1483 #endif
1484 
1485 	/* mfspr r3,n; blr */
1486 	instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1487 	instrs[1] = 0x4e800020;
1488 	store_inst(instrs);
1489 	store_inst(instrs+1);
1490 
1491 	if (setjmp(bus_error_jmp) == 0) {
1492 		catch_memory_errors = 1;
1493 		sync();
1494 
1495 		ret = code();
1496 
1497 		sync();
1498 		/* wait a little while to see if we get a machine check */
1499 		__delay(200);
1500 		n = size;
1501 	}
1502 
1503 	return ret;
1504 }
1505 
1506 void
1507 write_spr(int n, unsigned long val)
1508 {
1509 	unsigned int instrs[2];
1510 	unsigned long (*code)(unsigned long);
1511 #ifdef CONFIG_PPC64
1512 	unsigned long opd[3];
1513 
1514 	opd[0] = (unsigned long)instrs;
1515 	opd[1] = 0;
1516 	opd[2] = 0;
1517 	code = (unsigned long (*)(unsigned long)) opd;
1518 #else
1519 	code = (unsigned long (*)(unsigned long)) instrs;
1520 #endif
1521 
1522 	instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1523 	instrs[1] = 0x4e800020;
1524 	store_inst(instrs);
1525 	store_inst(instrs+1);
1526 
1527 	if (setjmp(bus_error_jmp) == 0) {
1528 		catch_memory_errors = 1;
1529 		sync();
1530 
1531 		code(val);
1532 
1533 		sync();
1534 		/* wait a little while to see if we get a machine check */
1535 		__delay(200);
1536 		n = size;
1537 	}
1538 }
1539 
1540 static unsigned long regno;
1541 extern char exc_prolog;
1542 extern char dec_exc;
1543 
1544 void super_regs(void)
1545 {
1546 	int cmd;
1547 	unsigned long val;
1548 #ifdef CONFIG_PPC_ISERIES
1549 	struct paca_struct *ptrPaca = NULL;
1550 	struct lppaca *ptrLpPaca = NULL;
1551 	struct ItLpRegSave *ptrLpRegSave = NULL;
1552 #endif
1553 
1554 	cmd = skipbl();
1555 	if (cmd == '\n') {
1556 	        unsigned long sp, toc;
1557 		asm("mr %0,1" : "=r" (sp) :);
1558 		asm("mr %0,2" : "=r" (toc) :);
1559 
1560 		printf("msr  = "REG"  sprg0= "REG"\n",
1561 		       mfmsr(), mfspr(SPRN_SPRG0));
1562 		printf("pvr  = "REG"  sprg1= "REG"\n",
1563 		       mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
1564 		printf("dec  = "REG"  sprg2= "REG"\n",
1565 		       mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1566 		printf("sp   = "REG"  sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1567 		printf("toc  = "REG"  dar  = "REG"\n", toc, mfspr(SPRN_DAR));
1568 #ifdef CONFIG_PPC_ISERIES
1569 		// Dump out relevant Paca data areas.
1570 		printf("Paca: \n");
1571 		ptrPaca = get_paca();
1572 
1573 		printf("  Local Processor Control Area (LpPaca): \n");
1574 		ptrLpPaca = ptrPaca->lppaca_ptr;
1575 		printf("    Saved Srr0=%.16lx  Saved Srr1=%.16lx \n",
1576 		       ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
1577 		printf("    Saved Gpr3=%.16lx  Saved Gpr4=%.16lx \n",
1578 		       ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
1579 		printf("    Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
1580 
1581 		printf("  Local Processor Register Save Area (LpRegSave): \n");
1582 		ptrLpRegSave = ptrPaca->reg_save_ptr;
1583 		printf("    Saved Sprg0=%.16lx  Saved Sprg1=%.16lx \n",
1584 		       ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
1585 		printf("    Saved Sprg2=%.16lx  Saved Sprg3=%.16lx \n",
1586 		       ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
1587 		printf("    Saved Msr  =%.16lx  Saved Nia  =%.16lx \n",
1588 		       ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
1589 #endif
1590 
1591 		return;
1592 	}
1593 
1594 	scanhex(&regno);
1595 	switch (cmd) {
1596 	case 'w':
1597 		val = read_spr(regno);
1598 		scanhex(&val);
1599 		write_spr(regno, val);
1600 		/* fall through */
1601 	case 'r':
1602 		printf("spr %lx = %lx\n", regno, read_spr(regno));
1603 		break;
1604 	}
1605 	scannl();
1606 }
1607 
1608 /*
1609  * Stuff for reading and writing memory safely
1610  */
1611 int
1612 mread(unsigned long adrs, void *buf, int size)
1613 {
1614 	volatile int n;
1615 	char *p, *q;
1616 
1617 	n = 0;
1618 	if (setjmp(bus_error_jmp) == 0) {
1619 		catch_memory_errors = 1;
1620 		sync();
1621 		p = (char *)adrs;
1622 		q = (char *)buf;
1623 		switch (size) {
1624 		case 2:
1625 			*(u16 *)q = *(u16 *)p;
1626 			break;
1627 		case 4:
1628 			*(u32 *)q = *(u32 *)p;
1629 			break;
1630 		case 8:
1631 			*(u64 *)q = *(u64 *)p;
1632 			break;
1633 		default:
1634 			for( ; n < size; ++n) {
1635 				*q++ = *p++;
1636 				sync();
1637 			}
1638 		}
1639 		sync();
1640 		/* wait a little while to see if we get a machine check */
1641 		__delay(200);
1642 		n = size;
1643 	}
1644 	catch_memory_errors = 0;
1645 	return n;
1646 }
1647 
1648 int
1649 mwrite(unsigned long adrs, void *buf, int size)
1650 {
1651 	volatile int n;
1652 	char *p, *q;
1653 
1654 	n = 0;
1655 	if (setjmp(bus_error_jmp) == 0) {
1656 		catch_memory_errors = 1;
1657 		sync();
1658 		p = (char *) adrs;
1659 		q = (char *) buf;
1660 		switch (size) {
1661 		case 2:
1662 			*(u16 *)p = *(u16 *)q;
1663 			break;
1664 		case 4:
1665 			*(u32 *)p = *(u32 *)q;
1666 			break;
1667 		case 8:
1668 			*(u64 *)p = *(u64 *)q;
1669 			break;
1670 		default:
1671 			for ( ; n < size; ++n) {
1672 				*p++ = *q++;
1673 				sync();
1674 			}
1675 		}
1676 		sync();
1677 		/* wait a little while to see if we get a machine check */
1678 		__delay(200);
1679 		n = size;
1680 	} else {
1681 		printf("*** Error writing address %x\n", adrs + n);
1682 	}
1683 	catch_memory_errors = 0;
1684 	return n;
1685 }
1686 
1687 static int fault_type;
1688 static int fault_except;
1689 static char *fault_chars[] = { "--", "**", "##" };
1690 
1691 static int handle_fault(struct pt_regs *regs)
1692 {
1693 	fault_except = TRAP(regs);
1694 	switch (TRAP(regs)) {
1695 	case 0x200:
1696 		fault_type = 0;
1697 		break;
1698 	case 0x300:
1699 	case 0x380:
1700 		fault_type = 1;
1701 		break;
1702 	default:
1703 		fault_type = 2;
1704 	}
1705 
1706 	longjmp(bus_error_jmp, 1);
1707 
1708 	return 0;
1709 }
1710 
1711 #define SWAP(a, b, t)	((t) = (a), (a) = (b), (b) = (t))
1712 
1713 void
1714 byterev(unsigned char *val, int size)
1715 {
1716 	int t;
1717 
1718 	switch (size) {
1719 	case 2:
1720 		SWAP(val[0], val[1], t);
1721 		break;
1722 	case 4:
1723 		SWAP(val[0], val[3], t);
1724 		SWAP(val[1], val[2], t);
1725 		break;
1726 	case 8: /* is there really any use for this? */
1727 		SWAP(val[0], val[7], t);
1728 		SWAP(val[1], val[6], t);
1729 		SWAP(val[2], val[5], t);
1730 		SWAP(val[3], val[4], t);
1731 		break;
1732 	}
1733 }
1734 
1735 static int brev;
1736 static int mnoread;
1737 
1738 static char *memex_help_string =
1739     "Memory examine command usage:\n"
1740     "m [addr] [flags] examine/change memory\n"
1741     "  addr is optional.  will start where left off.\n"
1742     "  flags may include chars from this set:\n"
1743     "    b   modify by bytes (default)\n"
1744     "    w   modify by words (2 byte)\n"
1745     "    l   modify by longs (4 byte)\n"
1746     "    d   modify by doubleword (8 byte)\n"
1747     "    r   toggle reverse byte order mode\n"
1748     "    n   do not read memory (for i/o spaces)\n"
1749     "    .   ok to read (default)\n"
1750     "NOTE: flags are saved as defaults\n"
1751     "";
1752 
1753 static char *memex_subcmd_help_string =
1754     "Memory examine subcommands:\n"
1755     "  hexval   write this val to current location\n"
1756     "  'string' write chars from string to this location\n"
1757     "  '        increment address\n"
1758     "  ^        decrement address\n"
1759     "  /        increment addr by 0x10.  //=0x100, ///=0x1000, etc\n"
1760     "  \\        decrement addr by 0x10.  \\\\=0x100, \\\\\\=0x1000, etc\n"
1761     "  `        clear no-read flag\n"
1762     "  ;        stay at this addr\n"
1763     "  v        change to byte mode\n"
1764     "  w        change to word (2 byte) mode\n"
1765     "  l        change to long (4 byte) mode\n"
1766     "  u        change to doubleword (8 byte) mode\n"
1767     "  m addr   change current addr\n"
1768     "  n        toggle no-read flag\n"
1769     "  r        toggle byte reverse flag\n"
1770     "  < count  back up count bytes\n"
1771     "  > count  skip forward count bytes\n"
1772     "  x        exit this mode\n"
1773     "";
1774 
1775 void
1776 memex(void)
1777 {
1778 	int cmd, inc, i, nslash;
1779 	unsigned long n;
1780 	unsigned char val[16];
1781 
1782 	scanhex((void *)&adrs);
1783 	cmd = skipbl();
1784 	if (cmd == '?') {
1785 		printf(memex_help_string);
1786 		return;
1787 	} else {
1788 		termch = cmd;
1789 	}
1790 	last_cmd = "m\n";
1791 	while ((cmd = skipbl()) != '\n') {
1792 		switch( cmd ){
1793 		case 'b':	size = 1;	break;
1794 		case 'w':	size = 2;	break;
1795 		case 'l':	size = 4;	break;
1796 		case 'd':	size = 8;	break;
1797 		case 'r': 	brev = !brev;	break;
1798 		case 'n':	mnoread = 1;	break;
1799 		case '.':	mnoread = 0;	break;
1800 		}
1801 	}
1802 	if( size <= 0 )
1803 		size = 1;
1804 	else if( size > 8 )
1805 		size = 8;
1806 	for(;;){
1807 		if (!mnoread)
1808 			n = mread(adrs, val, size);
1809 		printf(REG"%c", adrs, brev? 'r': ' ');
1810 		if (!mnoread) {
1811 			if (brev)
1812 				byterev(val, size);
1813 			putchar(' ');
1814 			for (i = 0; i < n; ++i)
1815 				printf("%.2x", val[i]);
1816 			for (; i < size; ++i)
1817 				printf("%s", fault_chars[fault_type]);
1818 		}
1819 		putchar(' ');
1820 		inc = size;
1821 		nslash = 0;
1822 		for(;;){
1823 			if( scanhex(&n) ){
1824 				for (i = 0; i < size; ++i)
1825 					val[i] = n >> (i * 8);
1826 				if (!brev)
1827 					byterev(val, size);
1828 				mwrite(adrs, val, size);
1829 				inc = size;
1830 			}
1831 			cmd = skipbl();
1832 			if (cmd == '\n')
1833 				break;
1834 			inc = 0;
1835 			switch (cmd) {
1836 			case '\'':
1837 				for(;;){
1838 					n = inchar();
1839 					if( n == '\\' )
1840 						n = bsesc();
1841 					else if( n == '\'' )
1842 						break;
1843 					for (i = 0; i < size; ++i)
1844 						val[i] = n >> (i * 8);
1845 					if (!brev)
1846 						byterev(val, size);
1847 					mwrite(adrs, val, size);
1848 					adrs += size;
1849 				}
1850 				adrs -= size;
1851 				inc = size;
1852 				break;
1853 			case ',':
1854 				adrs += size;
1855 				break;
1856 			case '.':
1857 				mnoread = 0;
1858 				break;
1859 			case ';':
1860 				break;
1861 			case 'x':
1862 			case EOF:
1863 				scannl();
1864 				return;
1865 			case 'b':
1866 			case 'v':
1867 				size = 1;
1868 				break;
1869 			case 'w':
1870 				size = 2;
1871 				break;
1872 			case 'l':
1873 				size = 4;
1874 				break;
1875 			case 'u':
1876 				size = 8;
1877 				break;
1878 			case '^':
1879 				adrs -= size;
1880 				break;
1881 				break;
1882 			case '/':
1883 				if (nslash > 0)
1884 					adrs -= 1 << nslash;
1885 				else
1886 					nslash = 0;
1887 				nslash += 4;
1888 				adrs += 1 << nslash;
1889 				break;
1890 			case '\\':
1891 				if (nslash < 0)
1892 					adrs += 1 << -nslash;
1893 				else
1894 					nslash = 0;
1895 				nslash -= 4;
1896 				adrs -= 1 << -nslash;
1897 				break;
1898 			case 'm':
1899 				scanhex((void *)&adrs);
1900 				break;
1901 			case 'n':
1902 				mnoread = 1;
1903 				break;
1904 			case 'r':
1905 				brev = !brev;
1906 				break;
1907 			case '<':
1908 				n = size;
1909 				scanhex(&n);
1910 				adrs -= n;
1911 				break;
1912 			case '>':
1913 				n = size;
1914 				scanhex(&n);
1915 				adrs += n;
1916 				break;
1917 			case '?':
1918 				printf(memex_subcmd_help_string);
1919 				break;
1920 			}
1921 		}
1922 		adrs += inc;
1923 	}
1924 }
1925 
1926 int
1927 bsesc(void)
1928 {
1929 	int c;
1930 
1931 	c = inchar();
1932 	switch( c ){
1933 	case 'n':	c = '\n';	break;
1934 	case 'r':	c = '\r';	break;
1935 	case 'b':	c = '\b';	break;
1936 	case 't':	c = '\t';	break;
1937 	}
1938 	return c;
1939 }
1940 
1941 #define isxdigit(c)	(('0' <= (c) && (c) <= '9') \
1942 			 || ('a' <= (c) && (c) <= 'f') \
1943 			 || ('A' <= (c) && (c) <= 'F'))
1944 void
1945 dump(void)
1946 {
1947 	int c;
1948 
1949 	c = inchar();
1950 	if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
1951 		termch = c;
1952 	scanhex((void *)&adrs);
1953 	if (termch != '\n')
1954 		termch = 0;
1955 	if (c == 'i') {
1956 		scanhex(&nidump);
1957 		if (nidump == 0)
1958 			nidump = 16;
1959 		else if (nidump > MAX_DUMP)
1960 			nidump = MAX_DUMP;
1961 		adrs += ppc_inst_dump(adrs, nidump, 1);
1962 		last_cmd = "di\n";
1963 	} else {
1964 		scanhex(&ndump);
1965 		if (ndump == 0)
1966 			ndump = 64;
1967 		else if (ndump > MAX_DUMP)
1968 			ndump = MAX_DUMP;
1969 		prdump(adrs, ndump);
1970 		adrs += ndump;
1971 		last_cmd = "d\n";
1972 	}
1973 }
1974 
1975 void
1976 prdump(unsigned long adrs, long ndump)
1977 {
1978 	long n, m, c, r, nr;
1979 	unsigned char temp[16];
1980 
1981 	for (n = ndump; n > 0;) {
1982 		printf(REG, adrs);
1983 		putchar(' ');
1984 		r = n < 16? n: 16;
1985 		nr = mread(adrs, temp, r);
1986 		adrs += nr;
1987 		for (m = 0; m < r; ++m) {
1988 		        if ((m & (sizeof(long) - 1)) == 0 && m > 0)
1989 				putchar(' ');
1990 			if (m < nr)
1991 				printf("%.2x", temp[m]);
1992 			else
1993 				printf("%s", fault_chars[fault_type]);
1994 		}
1995 		for (; m < 16; ++m) {
1996 		        if ((m & (sizeof(long) - 1)) == 0)
1997 				putchar(' ');
1998 			printf("  ");
1999 		}
2000 		printf("  |");
2001 		for (m = 0; m < r; ++m) {
2002 			if (m < nr) {
2003 				c = temp[m];
2004 				putchar(' ' <= c && c <= '~'? c: '.');
2005 			} else
2006 				putchar(' ');
2007 		}
2008 		n -= r;
2009 		for (; m < 16; ++m)
2010 			putchar(' ');
2011 		printf("|\n");
2012 		if (nr < r)
2013 			break;
2014 	}
2015 }
2016 
2017 int
2018 ppc_inst_dump(unsigned long adr, long count, int praddr)
2019 {
2020 	int nr, dotted;
2021 	unsigned long first_adr;
2022 	unsigned long inst, last_inst = 0;
2023 	unsigned char val[4];
2024 
2025 	dotted = 0;
2026 	for (first_adr = adr; count > 0; --count, adr += 4) {
2027 		nr = mread(adr, val, 4);
2028 		if (nr == 0) {
2029 			if (praddr) {
2030 				const char *x = fault_chars[fault_type];
2031 				printf(REG"  %s%s%s%s\n", adr, x, x, x, x);
2032 			}
2033 			break;
2034 		}
2035 		inst = GETWORD(val);
2036 		if (adr > first_adr && inst == last_inst) {
2037 			if (!dotted) {
2038 				printf(" ...\n");
2039 				dotted = 1;
2040 			}
2041 			continue;
2042 		}
2043 		dotted = 0;
2044 		last_inst = inst;
2045 		if (praddr)
2046 			printf(REG"  %.8x", adr, inst);
2047 		printf("\t");
2048 		print_insn_powerpc(inst, adr, 0);	/* always returns 4 */
2049 		printf("\n");
2050 	}
2051 	return adr - first_adr;
2052 }
2053 
2054 void
2055 print_address(unsigned long addr)
2056 {
2057 	xmon_print_symbol(addr, "\t# ", "");
2058 }
2059 
2060 
2061 /*
2062  * Memory operations - move, set, print differences
2063  */
2064 static unsigned long mdest;		/* destination address */
2065 static unsigned long msrc;		/* source address */
2066 static unsigned long mval;		/* byte value to set memory to */
2067 static unsigned long mcount;		/* # bytes to affect */
2068 static unsigned long mdiffs;		/* max # differences to print */
2069 
2070 void
2071 memops(int cmd)
2072 {
2073 	scanhex((void *)&mdest);
2074 	if( termch != '\n' )
2075 		termch = 0;
2076 	scanhex((void *)(cmd == 's'? &mval: &msrc));
2077 	if( termch != '\n' )
2078 		termch = 0;
2079 	scanhex((void *)&mcount);
2080 	switch( cmd ){
2081 	case 'm':
2082 		memmove((void *)mdest, (void *)msrc, mcount);
2083 		break;
2084 	case 's':
2085 		memset((void *)mdest, mval, mcount);
2086 		break;
2087 	case 'd':
2088 		if( termch != '\n' )
2089 			termch = 0;
2090 		scanhex((void *)&mdiffs);
2091 		memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2092 		break;
2093 	}
2094 }
2095 
2096 void
2097 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2098 {
2099 	unsigned n, prt;
2100 
2101 	prt = 0;
2102 	for( n = nb; n > 0; --n )
2103 		if( *p1++ != *p2++ )
2104 			if( ++prt <= maxpr )
2105 				printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2106 					p1[-1], p2 - 1, p2[-1]);
2107 	if( prt > maxpr )
2108 		printf("Total of %d differences\n", prt);
2109 }
2110 
2111 static unsigned mend;
2112 static unsigned mask;
2113 
2114 void
2115 memlocate(void)
2116 {
2117 	unsigned a, n;
2118 	unsigned char val[4];
2119 
2120 	last_cmd = "ml";
2121 	scanhex((void *)&mdest);
2122 	if (termch != '\n') {
2123 		termch = 0;
2124 		scanhex((void *)&mend);
2125 		if (termch != '\n') {
2126 			termch = 0;
2127 			scanhex((void *)&mval);
2128 			mask = ~0;
2129 			if (termch != '\n') termch = 0;
2130 			scanhex((void *)&mask);
2131 		}
2132 	}
2133 	n = 0;
2134 	for (a = mdest; a < mend; a += 4) {
2135 		if (mread(a, val, 4) == 4
2136 			&& ((GETWORD(val) ^ mval) & mask) == 0) {
2137 			printf("%.16x:  %.16x\n", a, GETWORD(val));
2138 			if (++n >= 10)
2139 				break;
2140 		}
2141 	}
2142 }
2143 
2144 static unsigned long mskip = 0x1000;
2145 static unsigned long mlim = 0xffffffff;
2146 
2147 void
2148 memzcan(void)
2149 {
2150 	unsigned char v;
2151 	unsigned a;
2152 	int ok, ook;
2153 
2154 	scanhex(&mdest);
2155 	if (termch != '\n') termch = 0;
2156 	scanhex(&mskip);
2157 	if (termch != '\n') termch = 0;
2158 	scanhex(&mlim);
2159 	ook = 0;
2160 	for (a = mdest; a < mlim; a += mskip) {
2161 		ok = mread(a, &v, 1);
2162 		if (ok && !ook) {
2163 			printf("%.8x .. ", a);
2164 		} else if (!ok && ook)
2165 			printf("%.8x\n", a - mskip);
2166 		ook = ok;
2167 		if (a + mskip < a)
2168 			break;
2169 	}
2170 	if (ook)
2171 		printf("%.8x\n", a - mskip);
2172 }
2173 
2174 void proccall(void)
2175 {
2176 	unsigned long args[8];
2177 	unsigned long ret;
2178 	int i;
2179 	typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2180 			unsigned long, unsigned long, unsigned long,
2181 			unsigned long, unsigned long, unsigned long);
2182 	callfunc_t func;
2183 
2184 	if (!scanhex(&adrs))
2185 		return;
2186 	if (termch != '\n')
2187 		termch = 0;
2188 	for (i = 0; i < 8; ++i)
2189 		args[i] = 0;
2190 	for (i = 0; i < 8; ++i) {
2191 		if (!scanhex(&args[i]) || termch == '\n')
2192 			break;
2193 		termch = 0;
2194 	}
2195 	func = (callfunc_t) adrs;
2196 	ret = 0;
2197 	if (setjmp(bus_error_jmp) == 0) {
2198 		catch_memory_errors = 1;
2199 		sync();
2200 		ret = func(args[0], args[1], args[2], args[3],
2201 			   args[4], args[5], args[6], args[7]);
2202 		sync();
2203 		printf("return value is %x\n", ret);
2204 	} else {
2205 		printf("*** %x exception occurred\n", fault_except);
2206 	}
2207 	catch_memory_errors = 0;
2208 }
2209 
2210 /* Input scanning routines */
2211 int
2212 skipbl(void)
2213 {
2214 	int c;
2215 
2216 	if( termch != 0 ){
2217 		c = termch;
2218 		termch = 0;
2219 	} else
2220 		c = inchar();
2221 	while( c == ' ' || c == '\t' )
2222 		c = inchar();
2223 	return c;
2224 }
2225 
2226 #define N_PTREGS	44
2227 static char *regnames[N_PTREGS] = {
2228 	"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2229 	"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2230 	"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2231 	"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2232 	"pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2233 #ifdef CONFIG_PPC64
2234 	"softe",
2235 #else
2236 	"mq",
2237 #endif
2238 	"trap", "dar", "dsisr", "res"
2239 };
2240 
2241 int
2242 scanhex(unsigned long *vp)
2243 {
2244 	int c, d;
2245 	unsigned long v;
2246 
2247 	c = skipbl();
2248 	if (c == '%') {
2249 		/* parse register name */
2250 		char regname[8];
2251 		int i;
2252 
2253 		for (i = 0; i < sizeof(regname) - 1; ++i) {
2254 			c = inchar();
2255 			if (!isalnum(c)) {
2256 				termch = c;
2257 				break;
2258 			}
2259 			regname[i] = c;
2260 		}
2261 		regname[i] = 0;
2262 		for (i = 0; i < N_PTREGS; ++i) {
2263 			if (strcmp(regnames[i], regname) == 0) {
2264 				if (xmon_regs == NULL) {
2265 					printf("regs not available\n");
2266 					return 0;
2267 				}
2268 				*vp = ((unsigned long *)xmon_regs)[i];
2269 				return 1;
2270 			}
2271 		}
2272 		printf("invalid register name '%%%s'\n", regname);
2273 		return 0;
2274 	}
2275 
2276 	/* skip leading "0x" if any */
2277 
2278 	if (c == '0') {
2279 		c = inchar();
2280 		if (c == 'x') {
2281 			c = inchar();
2282 		} else {
2283 			d = hexdigit(c);
2284 			if (d == EOF) {
2285 				termch = c;
2286 				*vp = 0;
2287 				return 1;
2288 			}
2289 		}
2290 	} else if (c == '$') {
2291 		int i;
2292 		for (i=0; i<63; i++) {
2293 			c = inchar();
2294 			if (isspace(c)) {
2295 				termch = c;
2296 				break;
2297 			}
2298 			tmpstr[i] = c;
2299 		}
2300 		tmpstr[i++] = 0;
2301 		*vp = 0;
2302 		if (setjmp(bus_error_jmp) == 0) {
2303 			catch_memory_errors = 1;
2304 			sync();
2305 			*vp = kallsyms_lookup_name(tmpstr);
2306 			sync();
2307 		}
2308 		catch_memory_errors = 0;
2309 		if (!(*vp)) {
2310 			printf("unknown symbol '%s'\n", tmpstr);
2311 			return 0;
2312 		}
2313 		return 1;
2314 	}
2315 
2316 	d = hexdigit(c);
2317 	if (d == EOF) {
2318 		termch = c;
2319 		return 0;
2320 	}
2321 	v = 0;
2322 	do {
2323 		v = (v << 4) + d;
2324 		c = inchar();
2325 		d = hexdigit(c);
2326 	} while (d != EOF);
2327 	termch = c;
2328 	*vp = v;
2329 	return 1;
2330 }
2331 
2332 void
2333 scannl(void)
2334 {
2335 	int c;
2336 
2337 	c = termch;
2338 	termch = 0;
2339 	while( c != '\n' )
2340 		c = inchar();
2341 }
2342 
2343 int hexdigit(int c)
2344 {
2345 	if( '0' <= c && c <= '9' )
2346 		return c - '0';
2347 	if( 'A' <= c && c <= 'F' )
2348 		return c - ('A' - 10);
2349 	if( 'a' <= c && c <= 'f' )
2350 		return c - ('a' - 10);
2351 	return EOF;
2352 }
2353 
2354 void
2355 getstring(char *s, int size)
2356 {
2357 	int c;
2358 
2359 	c = skipbl();
2360 	do {
2361 		if( size > 1 ){
2362 			*s++ = c;
2363 			--size;
2364 		}
2365 		c = inchar();
2366 	} while( c != ' ' && c != '\t' && c != '\n' );
2367 	termch = c;
2368 	*s = 0;
2369 }
2370 
2371 static char line[256];
2372 static char *lineptr;
2373 
2374 void
2375 flush_input(void)
2376 {
2377 	lineptr = NULL;
2378 }
2379 
2380 int
2381 inchar(void)
2382 {
2383 	if (lineptr == NULL || *lineptr == 0) {
2384 		if (xmon_gets(line, sizeof(line)) == NULL) {
2385 			lineptr = NULL;
2386 			return EOF;
2387 		}
2388 		lineptr = line;
2389 	}
2390 	return *lineptr++;
2391 }
2392 
2393 void
2394 take_input(char *str)
2395 {
2396 	lineptr = str;
2397 }
2398 
2399 
2400 static void
2401 symbol_lookup(void)
2402 {
2403 	int type = inchar();
2404 	unsigned long addr;
2405 	static char tmp[64];
2406 
2407 	switch (type) {
2408 	case 'a':
2409 		if (scanhex(&addr))
2410 			xmon_print_symbol(addr, ": ", "\n");
2411 		termch = 0;
2412 		break;
2413 	case 's':
2414 		getstring(tmp, 64);
2415 		if (setjmp(bus_error_jmp) == 0) {
2416 			catch_memory_errors = 1;
2417 			sync();
2418 			addr = kallsyms_lookup_name(tmp);
2419 			if (addr)
2420 				printf("%s: %lx\n", tmp, addr);
2421 			else
2422 				printf("Symbol '%s' not found.\n", tmp);
2423 			sync();
2424 		}
2425 		catch_memory_errors = 0;
2426 		termch = 0;
2427 		break;
2428 	}
2429 }
2430 
2431 
2432 /* Print an address in numeric and symbolic form (if possible) */
2433 static void xmon_print_symbol(unsigned long address, const char *mid,
2434 			      const char *after)
2435 {
2436 	char *modname;
2437 	const char *name = NULL;
2438 	unsigned long offset, size;
2439 
2440 	printf(REG, address);
2441 	if (setjmp(bus_error_jmp) == 0) {
2442 		catch_memory_errors = 1;
2443 		sync();
2444 		name = kallsyms_lookup(address, &size, &offset, &modname,
2445 				       tmpstr);
2446 		sync();
2447 		/* wait a little while to see if we get a machine check */
2448 		__delay(200);
2449 	}
2450 
2451 	catch_memory_errors = 0;
2452 
2453 	if (name) {
2454 		printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2455 		if (modname)
2456 			printf(" [%s]", modname);
2457 	}
2458 	printf("%s", after);
2459 }
2460 
2461 #ifdef CONFIG_PPC64
2462 static void dump_slb(void)
2463 {
2464 	int i;
2465 	unsigned long tmp;
2466 
2467 	printf("SLB contents of cpu %x\n", smp_processor_id());
2468 
2469 	for (i = 0; i < SLB_NUM_ENTRIES; i++) {
2470 		asm volatile("slbmfee  %0,%1" : "=r" (tmp) : "r" (i));
2471 		printf("%02d %016lx ", i, tmp);
2472 
2473 		asm volatile("slbmfev  %0,%1" : "=r" (tmp) : "r" (i));
2474 		printf("%016lx\n", tmp);
2475 	}
2476 }
2477 
2478 static void dump_stab(void)
2479 {
2480 	int i;
2481 	unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2482 
2483 	printf("Segment table contents of cpu %x\n", smp_processor_id());
2484 
2485 	for (i = 0; i < PAGE_SIZE/16; i++) {
2486 		unsigned long a, b;
2487 
2488 		a = *tmp++;
2489 		b = *tmp++;
2490 
2491 		if (a || b) {
2492 			printf("%03d %016lx ", i, a);
2493 			printf("%016lx\n", b);
2494 		}
2495 	}
2496 }
2497 
2498 void dump_segments(void)
2499 {
2500 	if (cpu_has_feature(CPU_FTR_SLB))
2501 		dump_slb();
2502 	else
2503 		dump_stab();
2504 }
2505 #endif
2506 
2507 #ifdef CONFIG_PPC_STD_MMU_32
2508 void dump_segments(void)
2509 {
2510 	int i;
2511 
2512 	printf("sr0-15 =");
2513 	for (i = 0; i < 16; ++i)
2514 		printf(" %x", mfsrin(i));
2515 	printf("\n");
2516 }
2517 #endif
2518 
2519 void xmon_init(int enable)
2520 {
2521 	if (enable) {
2522 		__debugger = xmon;
2523 		__debugger_ipi = xmon_ipi;
2524 		__debugger_bpt = xmon_bpt;
2525 		__debugger_sstep = xmon_sstep;
2526 		__debugger_iabr_match = xmon_iabr_match;
2527 		__debugger_dabr_match = xmon_dabr_match;
2528 		__debugger_fault_handler = xmon_fault_handler;
2529 	} else {
2530 		__debugger = NULL;
2531 		__debugger_ipi = NULL;
2532 		__debugger_bpt = NULL;
2533 		__debugger_sstep = NULL;
2534 		__debugger_iabr_match = NULL;
2535 		__debugger_dabr_match = NULL;
2536 		__debugger_fault_handler = NULL;
2537 	}
2538 	xmon_map_scc();
2539 }
2540 
2541 #ifdef CONFIG_MAGIC_SYSRQ
2542 static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs,
2543 			      struct tty_struct *tty)
2544 {
2545 	/* ensure xmon is enabled */
2546 	xmon_init(1);
2547 	debugger(pt_regs);
2548 }
2549 
2550 static struct sysrq_key_op sysrq_xmon_op =
2551 {
2552 	.handler =	sysrq_handle_xmon,
2553 	.help_msg =	"Xmon",
2554 	.action_msg =	"Entering xmon",
2555 };
2556 
2557 static int __init setup_xmon_sysrq(void)
2558 {
2559 	register_sysrq_key('x', &sysrq_xmon_op);
2560 	return 0;
2561 }
2562 __initcall(setup_xmon_sysrq);
2563 #endif /* CONFIG_MAGIC_SYSRQ */
2564