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