xref: /linux/arch/powerpc/xmon/xmon.c (revision f3d9478b2ce468c3115b02ecae7e975990697f15)
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   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 	for(;;) {
744 #ifdef CONFIG_SMP
745 		printf("%x:", smp_processor_id());
746 #endif /* CONFIG_SMP */
747 		printf("mon> ");
748 		flush_input();
749 		termch = 0;
750 		cmd = skipbl();
751 		if( cmd == '\n' ) {
752 			if (last_cmd == NULL)
753 				continue;
754 			take_input(last_cmd);
755 			last_cmd = NULL;
756 			cmd = inchar();
757 		}
758 		switch (cmd) {
759 		case 'm':
760 			cmd = inchar();
761 			switch (cmd) {
762 			case 'm':
763 			case 's':
764 			case 'd':
765 				memops(cmd);
766 				break;
767 			case 'l':
768 				memlocate();
769 				break;
770 			case 'z':
771 				memzcan();
772 				break;
773 			case 'i':
774 				show_mem();
775 				break;
776 			default:
777 				termch = cmd;
778 				memex();
779 			}
780 			break;
781 		case 'd':
782 			dump();
783 			break;
784 		case 'l':
785 			symbol_lookup();
786 			break;
787 		case 'r':
788 			prregs(excp);	/* print regs */
789 			break;
790 		case 'e':
791 			excprint(excp);
792 			break;
793 		case 'S':
794 			super_regs();
795 			break;
796 		case 't':
797 			backtrace(excp);
798 			break;
799 		case 'f':
800 			cacheflush();
801 			break;
802 		case 's':
803 			if (do_step(excp))
804 				return cmd;
805 			break;
806 		case 'x':
807 		case 'X':
808 			return cmd;
809 		case EOF:
810 			printf(" <no input ...>\n");
811 			mdelay(2000);
812 			return cmd;
813 		case '?':
814 			printf(help_string);
815 			break;
816 		case 'b':
817 			bpt_cmds();
818 			break;
819 		case 'C':
820 			csum();
821 			break;
822 		case 'c':
823 			if (cpu_cmd())
824 				return 0;
825 			break;
826 		case 'z':
827 			bootcmds();
828 			break;
829 		case 'p':
830 			proccall();
831 			break;
832 #ifdef CONFIG_PPC_STD_MMU
833 		case 'u':
834 			dump_segments();
835 			break;
836 #endif
837 		default:
838 			printf("Unrecognized command: ");
839 		        do {
840 				if (' ' < cmd && cmd <= '~')
841 					putchar(cmd);
842 				else
843 					printf("\\x%x", cmd);
844 				cmd = inchar();
845 		        } while (cmd != '\n');
846 			printf(" (type ? for help)\n");
847 			break;
848 		}
849 	}
850 }
851 
852 /*
853  * Step a single instruction.
854  * Some instructions we emulate, others we execute with MSR_SE set.
855  */
856 static int do_step(struct pt_regs *regs)
857 {
858 	unsigned int instr;
859 	int stepped;
860 
861 	/* check we are in 64-bit kernel mode, translation enabled */
862 	if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
863 		if (mread(regs->nip, &instr, 4) == 4) {
864 			stepped = emulate_step(regs, instr);
865 			if (stepped < 0) {
866 				printf("Couldn't single-step %s instruction\n",
867 				       (IS_RFID(instr)? "rfid": "mtmsrd"));
868 				return 0;
869 			}
870 			if (stepped > 0) {
871 				regs->trap = 0xd00 | (regs->trap & 1);
872 				printf("stepped to ");
873 				xmon_print_symbol(regs->nip, " ", "\n");
874 				ppc_inst_dump(regs->nip, 1, 0);
875 				return 0;
876 			}
877 		}
878 	}
879 	regs->msr |= MSR_SE;
880 	return 1;
881 }
882 
883 static void bootcmds(void)
884 {
885 	int cmd;
886 
887 	cmd = inchar();
888 	if (cmd == 'r')
889 		ppc_md.restart(NULL);
890 	else if (cmd == 'h')
891 		ppc_md.halt();
892 	else if (cmd == 'p')
893 		ppc_md.power_off();
894 }
895 
896 static int cpu_cmd(void)
897 {
898 #ifdef CONFIG_SMP
899 	unsigned long cpu;
900 	int timeout;
901 	int count;
902 
903 	if (!scanhex(&cpu)) {
904 		/* print cpus waiting or in xmon */
905 		printf("cpus stopped:");
906 		count = 0;
907 		for (cpu = 0; cpu < NR_CPUS; ++cpu) {
908 			if (cpu_isset(cpu, cpus_in_xmon)) {
909 				if (count == 0)
910 					printf(" %x", cpu);
911 				++count;
912 			} else {
913 				if (count > 1)
914 					printf("-%x", cpu - 1);
915 				count = 0;
916 			}
917 		}
918 		if (count > 1)
919 			printf("-%x", NR_CPUS - 1);
920 		printf("\n");
921 		return 0;
922 	}
923 	/* try to switch to cpu specified */
924 	if (!cpu_isset(cpu, cpus_in_xmon)) {
925 		printf("cpu 0x%x isn't in xmon\n", cpu);
926 		return 0;
927 	}
928 	xmon_taken = 0;
929 	mb();
930 	xmon_owner = cpu;
931 	timeout = 10000000;
932 	while (!xmon_taken) {
933 		if (--timeout == 0) {
934 			if (test_and_set_bit(0, &xmon_taken))
935 				break;
936 			/* take control back */
937 			mb();
938 			xmon_owner = smp_processor_id();
939 			printf("cpu %u didn't take control\n", cpu);
940 			return 0;
941 		}
942 		barrier();
943 	}
944 	return 1;
945 #else
946 	return 0;
947 #endif /* CONFIG_SMP */
948 }
949 
950 static unsigned short fcstab[256] = {
951 	0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
952 	0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
953 	0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
954 	0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
955 	0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
956 	0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
957 	0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
958 	0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
959 	0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
960 	0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
961 	0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
962 	0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
963 	0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
964 	0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
965 	0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
966 	0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
967 	0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
968 	0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
969 	0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
970 	0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
971 	0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
972 	0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
973 	0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
974 	0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
975 	0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
976 	0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
977 	0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
978 	0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
979 	0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
980 	0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
981 	0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
982 	0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
983 };
984 
985 #define FCS(fcs, c)	(((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
986 
987 static void
988 csum(void)
989 {
990 	unsigned int i;
991 	unsigned short fcs;
992 	unsigned char v;
993 
994 	if (!scanhex(&adrs))
995 		return;
996 	if (!scanhex(&ncsum))
997 		return;
998 	fcs = 0xffff;
999 	for (i = 0; i < ncsum; ++i) {
1000 		if (mread(adrs+i, &v, 1) == 0) {
1001 			printf("csum stopped at %x\n", adrs+i);
1002 			break;
1003 		}
1004 		fcs = FCS(fcs, v);
1005 	}
1006 	printf("%x\n", fcs);
1007 }
1008 
1009 /*
1010  * Check if this is a suitable place to put a breakpoint.
1011  */
1012 static long check_bp_loc(unsigned long addr)
1013 {
1014 	unsigned int instr;
1015 
1016 	addr &= ~3;
1017 	if (!is_kernel_addr(addr)) {
1018 		printf("Breakpoints may only be placed at kernel addresses\n");
1019 		return 0;
1020 	}
1021 	if (!mread(addr, &instr, sizeof(instr))) {
1022 		printf("Can't read instruction at address %lx\n", addr);
1023 		return 0;
1024 	}
1025 	if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1026 		printf("Breakpoints may not be placed on mtmsrd or rfid "
1027 		       "instructions\n");
1028 		return 0;
1029 	}
1030 	return 1;
1031 }
1032 
1033 static char *breakpoint_help_string =
1034     "Breakpoint command usage:\n"
1035     "b                show breakpoints\n"
1036     "b <addr> [cnt]   set breakpoint at given instr addr\n"
1037     "bc               clear all breakpoints\n"
1038     "bc <n/addr>      clear breakpoint number n or at addr\n"
1039     "bi <addr> [cnt]  set hardware instr breakpoint (POWER3/RS64 only)\n"
1040     "bd <addr> [cnt]  set hardware data breakpoint\n"
1041     "";
1042 
1043 static void
1044 bpt_cmds(void)
1045 {
1046 	int cmd;
1047 	unsigned long a;
1048 	int mode, i;
1049 	struct bpt *bp;
1050 	const char badaddr[] = "Only kernel addresses are permitted "
1051 		"for breakpoints\n";
1052 
1053 	cmd = inchar();
1054 	switch (cmd) {
1055 #ifndef CONFIG_8xx
1056 	case 'd':	/* bd - hardware data breakpoint */
1057 		mode = 7;
1058 		cmd = inchar();
1059 		if (cmd == 'r')
1060 			mode = 5;
1061 		else if (cmd == 'w')
1062 			mode = 6;
1063 		else
1064 			termch = cmd;
1065 		dabr.address = 0;
1066 		dabr.enabled = 0;
1067 		if (scanhex(&dabr.address)) {
1068 			if (!is_kernel_addr(dabr.address)) {
1069 				printf(badaddr);
1070 				break;
1071 			}
1072 			dabr.address &= ~7;
1073 			dabr.enabled = mode | BP_DABR;
1074 		}
1075 		break;
1076 
1077 	case 'i':	/* bi - hardware instr breakpoint */
1078 		if (!cpu_has_feature(CPU_FTR_IABR)) {
1079 			printf("Hardware instruction breakpoint "
1080 			       "not supported on this cpu\n");
1081 			break;
1082 		}
1083 		if (iabr) {
1084 			iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1085 			iabr = NULL;
1086 		}
1087 		if (!scanhex(&a))
1088 			break;
1089 		if (!check_bp_loc(a))
1090 			break;
1091 		bp = new_breakpoint(a);
1092 		if (bp != NULL) {
1093 			bp->enabled |= BP_IABR | BP_IABR_TE;
1094 			iabr = bp;
1095 		}
1096 		break;
1097 #endif
1098 
1099 	case 'c':
1100 		if (!scanhex(&a)) {
1101 			/* clear all breakpoints */
1102 			for (i = 0; i < NBPTS; ++i)
1103 				bpts[i].enabled = 0;
1104 			iabr = NULL;
1105 			dabr.enabled = 0;
1106 			printf("All breakpoints cleared\n");
1107 			break;
1108 		}
1109 
1110 		if (a <= NBPTS && a >= 1) {
1111 			/* assume a breakpoint number */
1112 			bp = &bpts[a-1];	/* bp nums are 1 based */
1113 		} else {
1114 			/* assume a breakpoint address */
1115 			bp = at_breakpoint(a);
1116 			if (bp == 0) {
1117 				printf("No breakpoint at %x\n", a);
1118 				break;
1119 			}
1120 		}
1121 
1122 		printf("Cleared breakpoint %x (", BP_NUM(bp));
1123 		xmon_print_symbol(bp->address, " ", ")\n");
1124 		bp->enabled = 0;
1125 		break;
1126 
1127 	default:
1128 		termch = cmd;
1129 	        cmd = skipbl();
1130 		if (cmd == '?') {
1131 			printf(breakpoint_help_string);
1132 			break;
1133 		}
1134 		termch = cmd;
1135 		if (!scanhex(&a)) {
1136 			/* print all breakpoints */
1137 			printf("   type            address\n");
1138 			if (dabr.enabled) {
1139 				printf("   data   "REG"  [", dabr.address);
1140 				if (dabr.enabled & 1)
1141 					printf("r");
1142 				if (dabr.enabled & 2)
1143 					printf("w");
1144 				printf("]\n");
1145 			}
1146 			for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1147 				if (!bp->enabled)
1148 					continue;
1149 				printf("%2x %s   ", BP_NUM(bp),
1150 				    (bp->enabled & BP_IABR)? "inst": "trap");
1151 				xmon_print_symbol(bp->address, "  ", "\n");
1152 			}
1153 			break;
1154 		}
1155 
1156 		if (!check_bp_loc(a))
1157 			break;
1158 		bp = new_breakpoint(a);
1159 		if (bp != NULL)
1160 			bp->enabled |= BP_TRAP;
1161 		break;
1162 	}
1163 }
1164 
1165 /* Very cheap human name for vector lookup. */
1166 static
1167 const char *getvecname(unsigned long vec)
1168 {
1169 	char *ret;
1170 
1171 	switch (vec) {
1172 	case 0x100:	ret = "(System Reset)"; break;
1173 	case 0x200:	ret = "(Machine Check)"; break;
1174 	case 0x300:	ret = "(Data Access)"; break;
1175 	case 0x380:	ret = "(Data SLB Access)"; break;
1176 	case 0x400:	ret = "(Instruction Access)"; break;
1177 	case 0x480:	ret = "(Instruction SLB Access)"; break;
1178 	case 0x500:	ret = "(Hardware Interrupt)"; break;
1179 	case 0x600:	ret = "(Alignment)"; break;
1180 	case 0x700:	ret = "(Program Check)"; break;
1181 	case 0x800:	ret = "(FPU Unavailable)"; break;
1182 	case 0x900:	ret = "(Decrementer)"; break;
1183 	case 0xc00:	ret = "(System Call)"; break;
1184 	case 0xd00:	ret = "(Single Step)"; break;
1185 	case 0xf00:	ret = "(Performance Monitor)"; break;
1186 	case 0xf20:	ret = "(Altivec Unavailable)"; break;
1187 	case 0x1300:	ret = "(Instruction Breakpoint)"; break;
1188 	default: ret = "";
1189 	}
1190 	return ret;
1191 }
1192 
1193 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1194 				unsigned long *endp)
1195 {
1196 	unsigned long size, offset;
1197 	const char *name;
1198 	char *modname;
1199 
1200 	*startp = *endp = 0;
1201 	if (pc == 0)
1202 		return;
1203 	if (setjmp(bus_error_jmp) == 0) {
1204 		catch_memory_errors = 1;
1205 		sync();
1206 		name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr);
1207 		if (name != NULL) {
1208 			*startp = pc - offset;
1209 			*endp = pc - offset + size;
1210 		}
1211 		sync();
1212 	}
1213 	catch_memory_errors = 0;
1214 }
1215 
1216 static int xmon_depth_to_print = 64;
1217 
1218 #ifdef CONFIG_PPC64
1219 #define LRSAVE_OFFSET		0x10
1220 #define REG_FRAME_MARKER	0x7265677368657265ul	/* "regshere" */
1221 #define MARKER_OFFSET		0x60
1222 #define REGS_OFFSET		0x70
1223 #else
1224 #define LRSAVE_OFFSET		4
1225 #define REG_FRAME_MARKER	0x72656773
1226 #define MARKER_OFFSET		8
1227 #define REGS_OFFSET		16
1228 #endif
1229 
1230 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1231 			    unsigned long pc)
1232 {
1233 	unsigned long ip;
1234 	unsigned long newsp;
1235 	unsigned long marker;
1236 	int count = 0;
1237 	struct pt_regs regs;
1238 
1239 	do {
1240 		if (sp < PAGE_OFFSET) {
1241 			if (sp != 0)
1242 				printf("SP (%lx) is in userspace\n", sp);
1243 			break;
1244 		}
1245 
1246 		if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1247 		    || !mread(sp, &newsp, sizeof(unsigned long))) {
1248 			printf("Couldn't read stack frame at %lx\n", sp);
1249 			break;
1250 		}
1251 
1252 		/*
1253 		 * For the first stack frame, try to work out if
1254 		 * LR and/or the saved LR value in the bottommost
1255 		 * stack frame are valid.
1256 		 */
1257 		if ((pc | lr) != 0) {
1258 			unsigned long fnstart, fnend;
1259 			unsigned long nextip;
1260 			int printip = 1;
1261 
1262 			get_function_bounds(pc, &fnstart, &fnend);
1263 			nextip = 0;
1264 			if (newsp > sp)
1265 				mread(newsp + LRSAVE_OFFSET, &nextip,
1266 				      sizeof(unsigned long));
1267 			if (lr == ip) {
1268 				if (lr < PAGE_OFFSET
1269 				    || (fnstart <= lr && lr < fnend))
1270 					printip = 0;
1271 			} else if (lr == nextip) {
1272 				printip = 0;
1273 			} else if (lr >= PAGE_OFFSET
1274 				   && !(fnstart <= lr && lr < fnend)) {
1275 				printf("[link register   ] ");
1276 				xmon_print_symbol(lr, " ", "\n");
1277 			}
1278 			if (printip) {
1279 				printf("["REG"] ", sp);
1280 				xmon_print_symbol(ip, " ", " (unreliable)\n");
1281 			}
1282 			pc = lr = 0;
1283 
1284 		} else {
1285 			printf("["REG"] ", sp);
1286 			xmon_print_symbol(ip, " ", "\n");
1287 		}
1288 
1289 		/* Look for "regshere" marker to see if this is
1290 		   an exception frame. */
1291 		if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1292 		    && marker == REG_FRAME_MARKER) {
1293 			if (mread(sp + REGS_OFFSET, &regs, sizeof(regs))
1294 			    != sizeof(regs)) {
1295 				printf("Couldn't read registers at %lx\n",
1296 				       sp + REGS_OFFSET);
1297 				break;
1298 			}
1299                         printf("--- Exception: %lx %s at ", regs.trap,
1300 			       getvecname(TRAP(&regs)));
1301 			pc = regs.nip;
1302 			lr = regs.link;
1303 			xmon_print_symbol(pc, " ", "\n");
1304 		}
1305 
1306 		if (newsp == 0)
1307 			break;
1308 
1309 		sp = newsp;
1310 	} while (count++ < xmon_depth_to_print);
1311 }
1312 
1313 static void backtrace(struct pt_regs *excp)
1314 {
1315 	unsigned long sp;
1316 
1317 	if (scanhex(&sp))
1318 		xmon_show_stack(sp, 0, 0);
1319 	else
1320 		xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1321 	scannl();
1322 }
1323 
1324 static void print_bug_trap(struct pt_regs *regs)
1325 {
1326 	struct bug_entry *bug;
1327 	unsigned long addr;
1328 
1329 	if (regs->msr & MSR_PR)
1330 		return;		/* not in kernel */
1331 	addr = regs->nip;	/* address of trap instruction */
1332 	if (addr < PAGE_OFFSET)
1333 		return;
1334 	bug = find_bug(regs->nip);
1335 	if (bug == NULL)
1336 		return;
1337 	if (bug->line & BUG_WARNING_TRAP)
1338 		return;
1339 
1340 	printf("kernel BUG in %s at %s:%d!\n",
1341 	       bug->function, bug->file, (unsigned int)bug->line);
1342 }
1343 
1344 void excprint(struct pt_regs *fp)
1345 {
1346 	unsigned long trap;
1347 
1348 #ifdef CONFIG_SMP
1349 	printf("cpu 0x%x: ", smp_processor_id());
1350 #endif /* CONFIG_SMP */
1351 
1352 	trap = TRAP(fp);
1353 	printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1354 	printf("    pc: ");
1355 	xmon_print_symbol(fp->nip, ": ", "\n");
1356 
1357 	printf("    lr: ", fp->link);
1358 	xmon_print_symbol(fp->link, ": ", "\n");
1359 
1360 	printf("    sp: %lx\n", fp->gpr[1]);
1361 	printf("   msr: %lx\n", fp->msr);
1362 
1363 	if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1364 		printf("   dar: %lx\n", fp->dar);
1365 		if (trap != 0x380)
1366 			printf(" dsisr: %lx\n", fp->dsisr);
1367 	}
1368 
1369 	printf("  current = 0x%lx\n", current);
1370 #ifdef CONFIG_PPC64
1371 	printf("  paca    = 0x%lx\n", get_paca());
1372 #endif
1373 	if (current) {
1374 		printf("    pid   = %ld, comm = %s\n",
1375 		       current->pid, current->comm);
1376 	}
1377 
1378 	if (trap == 0x700)
1379 		print_bug_trap(fp);
1380 }
1381 
1382 void prregs(struct pt_regs *fp)
1383 {
1384 	int n, trap;
1385 	unsigned long base;
1386 	struct pt_regs regs;
1387 
1388 	if (scanhex(&base)) {
1389 		if (setjmp(bus_error_jmp) == 0) {
1390 			catch_memory_errors = 1;
1391 			sync();
1392 			regs = *(struct pt_regs *)base;
1393 			sync();
1394 			__delay(200);
1395 		} else {
1396 			catch_memory_errors = 0;
1397 			printf("*** Error reading registers from "REG"\n",
1398 			       base);
1399 			return;
1400 		}
1401 		catch_memory_errors = 0;
1402 		fp = &regs;
1403 	}
1404 
1405 #ifdef CONFIG_PPC64
1406 	if (FULL_REGS(fp)) {
1407 		for (n = 0; n < 16; ++n)
1408 			printf("R%.2ld = "REG"   R%.2ld = "REG"\n",
1409 			       n, fp->gpr[n], n+16, fp->gpr[n+16]);
1410 	} else {
1411 		for (n = 0; n < 7; ++n)
1412 			printf("R%.2ld = "REG"   R%.2ld = "REG"\n",
1413 			       n, fp->gpr[n], n+7, fp->gpr[n+7]);
1414 	}
1415 #else
1416 	for (n = 0; n < 32; ++n) {
1417 		printf("R%.2d = %.8x%s", n, fp->gpr[n],
1418 		       (n & 3) == 3? "\n": "   ");
1419 		if (n == 12 && !FULL_REGS(fp)) {
1420 			printf("\n");
1421 			break;
1422 		}
1423 	}
1424 #endif
1425 	printf("pc  = ");
1426 	xmon_print_symbol(fp->nip, " ", "\n");
1427 	printf("lr  = ");
1428 	xmon_print_symbol(fp->link, " ", "\n");
1429 	printf("msr = "REG"   cr  = %.8lx\n", fp->msr, fp->ccr);
1430 	printf("ctr = "REG"   xer = "REG"   trap = %4lx\n",
1431 	       fp->ctr, fp->xer, fp->trap);
1432 	trap = TRAP(fp);
1433 	if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1434 		printf("dar = "REG"   dsisr = %.8lx\n", fp->dar, fp->dsisr);
1435 }
1436 
1437 void cacheflush(void)
1438 {
1439 	int cmd;
1440 	unsigned long nflush;
1441 
1442 	cmd = inchar();
1443 	if (cmd != 'i')
1444 		termch = cmd;
1445 	scanhex((void *)&adrs);
1446 	if (termch != '\n')
1447 		termch = 0;
1448 	nflush = 1;
1449 	scanhex(&nflush);
1450 	nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1451 	if (setjmp(bus_error_jmp) == 0) {
1452 		catch_memory_errors = 1;
1453 		sync();
1454 
1455 		if (cmd != 'i') {
1456 			for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1457 				cflush((void *) adrs);
1458 		} else {
1459 			for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1460 				cinval((void *) adrs);
1461 		}
1462 		sync();
1463 		/* wait a little while to see if we get a machine check */
1464 		__delay(200);
1465 	}
1466 	catch_memory_errors = 0;
1467 }
1468 
1469 unsigned long
1470 read_spr(int n)
1471 {
1472 	unsigned int instrs[2];
1473 	unsigned long (*code)(void);
1474 	unsigned long ret = -1UL;
1475 #ifdef CONFIG_PPC64
1476 	unsigned long opd[3];
1477 
1478 	opd[0] = (unsigned long)instrs;
1479 	opd[1] = 0;
1480 	opd[2] = 0;
1481 	code = (unsigned long (*)(void)) opd;
1482 #else
1483 	code = (unsigned long (*)(void)) instrs;
1484 #endif
1485 
1486 	/* mfspr r3,n; blr */
1487 	instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1488 	instrs[1] = 0x4e800020;
1489 	store_inst(instrs);
1490 	store_inst(instrs+1);
1491 
1492 	if (setjmp(bus_error_jmp) == 0) {
1493 		catch_memory_errors = 1;
1494 		sync();
1495 
1496 		ret = code();
1497 
1498 		sync();
1499 		/* wait a little while to see if we get a machine check */
1500 		__delay(200);
1501 		n = size;
1502 	}
1503 
1504 	return ret;
1505 }
1506 
1507 void
1508 write_spr(int n, unsigned long val)
1509 {
1510 	unsigned int instrs[2];
1511 	unsigned long (*code)(unsigned long);
1512 #ifdef CONFIG_PPC64
1513 	unsigned long opd[3];
1514 
1515 	opd[0] = (unsigned long)instrs;
1516 	opd[1] = 0;
1517 	opd[2] = 0;
1518 	code = (unsigned long (*)(unsigned long)) opd;
1519 #else
1520 	code = (unsigned long (*)(unsigned long)) instrs;
1521 #endif
1522 
1523 	instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1524 	instrs[1] = 0x4e800020;
1525 	store_inst(instrs);
1526 	store_inst(instrs+1);
1527 
1528 	if (setjmp(bus_error_jmp) == 0) {
1529 		catch_memory_errors = 1;
1530 		sync();
1531 
1532 		code(val);
1533 
1534 		sync();
1535 		/* wait a little while to see if we get a machine check */
1536 		__delay(200);
1537 		n = size;
1538 	}
1539 }
1540 
1541 static unsigned long regno;
1542 extern char exc_prolog;
1543 extern char dec_exc;
1544 
1545 void super_regs(void)
1546 {
1547 	int cmd;
1548 	unsigned long val;
1549 #ifdef CONFIG_PPC_ISERIES
1550 	struct paca_struct *ptrPaca = NULL;
1551 	struct lppaca *ptrLpPaca = NULL;
1552 	struct ItLpRegSave *ptrLpRegSave = NULL;
1553 #endif
1554 
1555 	cmd = skipbl();
1556 	if (cmd == '\n') {
1557 	        unsigned long sp, toc;
1558 		asm("mr %0,1" : "=r" (sp) :);
1559 		asm("mr %0,2" : "=r" (toc) :);
1560 
1561 		printf("msr  = "REG"  sprg0= "REG"\n",
1562 		       mfmsr(), mfspr(SPRN_SPRG0));
1563 		printf("pvr  = "REG"  sprg1= "REG"\n",
1564 		       mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
1565 		printf("dec  = "REG"  sprg2= "REG"\n",
1566 		       mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1567 		printf("sp   = "REG"  sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1568 		printf("toc  = "REG"  dar  = "REG"\n", toc, mfspr(SPRN_DAR));
1569 #ifdef CONFIG_PPC_ISERIES
1570 		// Dump out relevant Paca data areas.
1571 		printf("Paca: \n");
1572 		ptrPaca = get_paca();
1573 
1574 		printf("  Local Processor Control Area (LpPaca): \n");
1575 		ptrLpPaca = ptrPaca->lppaca_ptr;
1576 		printf("    Saved Srr0=%.16lx  Saved Srr1=%.16lx \n",
1577 		       ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
1578 		printf("    Saved Gpr3=%.16lx  Saved Gpr4=%.16lx \n",
1579 		       ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
1580 		printf("    Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
1581 
1582 		printf("  Local Processor Register Save Area (LpRegSave): \n");
1583 		ptrLpRegSave = ptrPaca->reg_save_ptr;
1584 		printf("    Saved Sprg0=%.16lx  Saved Sprg1=%.16lx \n",
1585 		       ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
1586 		printf("    Saved Sprg2=%.16lx  Saved Sprg3=%.16lx \n",
1587 		       ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
1588 		printf("    Saved Msr  =%.16lx  Saved Nia  =%.16lx \n",
1589 		       ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
1590 #endif
1591 
1592 		return;
1593 	}
1594 
1595 	scanhex(&regno);
1596 	switch (cmd) {
1597 	case 'w':
1598 		val = read_spr(regno);
1599 		scanhex(&val);
1600 		write_spr(regno, val);
1601 		/* fall through */
1602 	case 'r':
1603 		printf("spr %lx = %lx\n", regno, read_spr(regno));
1604 		break;
1605 	}
1606 	scannl();
1607 }
1608 
1609 /*
1610  * Stuff for reading and writing memory safely
1611  */
1612 int
1613 mread(unsigned long adrs, void *buf, int size)
1614 {
1615 	volatile int n;
1616 	char *p, *q;
1617 
1618 	n = 0;
1619 	if (setjmp(bus_error_jmp) == 0) {
1620 		catch_memory_errors = 1;
1621 		sync();
1622 		p = (char *)adrs;
1623 		q = (char *)buf;
1624 		switch (size) {
1625 		case 2:
1626 			*(u16 *)q = *(u16 *)p;
1627 			break;
1628 		case 4:
1629 			*(u32 *)q = *(u32 *)p;
1630 			break;
1631 		case 8:
1632 			*(u64 *)q = *(u64 *)p;
1633 			break;
1634 		default:
1635 			for( ; n < size; ++n) {
1636 				*q++ = *p++;
1637 				sync();
1638 			}
1639 		}
1640 		sync();
1641 		/* wait a little while to see if we get a machine check */
1642 		__delay(200);
1643 		n = size;
1644 	}
1645 	catch_memory_errors = 0;
1646 	return n;
1647 }
1648 
1649 int
1650 mwrite(unsigned long adrs, void *buf, int size)
1651 {
1652 	volatile int n;
1653 	char *p, *q;
1654 
1655 	n = 0;
1656 	if (setjmp(bus_error_jmp) == 0) {
1657 		catch_memory_errors = 1;
1658 		sync();
1659 		p = (char *) adrs;
1660 		q = (char *) buf;
1661 		switch (size) {
1662 		case 2:
1663 			*(u16 *)p = *(u16 *)q;
1664 			break;
1665 		case 4:
1666 			*(u32 *)p = *(u32 *)q;
1667 			break;
1668 		case 8:
1669 			*(u64 *)p = *(u64 *)q;
1670 			break;
1671 		default:
1672 			for ( ; n < size; ++n) {
1673 				*p++ = *q++;
1674 				sync();
1675 			}
1676 		}
1677 		sync();
1678 		/* wait a little while to see if we get a machine check */
1679 		__delay(200);
1680 		n = size;
1681 	} else {
1682 		printf("*** Error writing address %x\n", adrs + n);
1683 	}
1684 	catch_memory_errors = 0;
1685 	return n;
1686 }
1687 
1688 static int fault_type;
1689 static int fault_except;
1690 static char *fault_chars[] = { "--", "**", "##" };
1691 
1692 static int handle_fault(struct pt_regs *regs)
1693 {
1694 	fault_except = TRAP(regs);
1695 	switch (TRAP(regs)) {
1696 	case 0x200:
1697 		fault_type = 0;
1698 		break;
1699 	case 0x300:
1700 	case 0x380:
1701 		fault_type = 1;
1702 		break;
1703 	default:
1704 		fault_type = 2;
1705 	}
1706 
1707 	longjmp(bus_error_jmp, 1);
1708 
1709 	return 0;
1710 }
1711 
1712 #define SWAP(a, b, t)	((t) = (a), (a) = (b), (b) = (t))
1713 
1714 void
1715 byterev(unsigned char *val, int size)
1716 {
1717 	int t;
1718 
1719 	switch (size) {
1720 	case 2:
1721 		SWAP(val[0], val[1], t);
1722 		break;
1723 	case 4:
1724 		SWAP(val[0], val[3], t);
1725 		SWAP(val[1], val[2], t);
1726 		break;
1727 	case 8: /* is there really any use for this? */
1728 		SWAP(val[0], val[7], t);
1729 		SWAP(val[1], val[6], t);
1730 		SWAP(val[2], val[5], t);
1731 		SWAP(val[3], val[4], t);
1732 		break;
1733 	}
1734 }
1735 
1736 static int brev;
1737 static int mnoread;
1738 
1739 static char *memex_help_string =
1740     "Memory examine command usage:\n"
1741     "m [addr] [flags] examine/change memory\n"
1742     "  addr is optional.  will start where left off.\n"
1743     "  flags may include chars from this set:\n"
1744     "    b   modify by bytes (default)\n"
1745     "    w   modify by words (2 byte)\n"
1746     "    l   modify by longs (4 byte)\n"
1747     "    d   modify by doubleword (8 byte)\n"
1748     "    r   toggle reverse byte order mode\n"
1749     "    n   do not read memory (for i/o spaces)\n"
1750     "    .   ok to read (default)\n"
1751     "NOTE: flags are saved as defaults\n"
1752     "";
1753 
1754 static char *memex_subcmd_help_string =
1755     "Memory examine subcommands:\n"
1756     "  hexval   write this val to current location\n"
1757     "  'string' write chars from string to this location\n"
1758     "  '        increment address\n"
1759     "  ^        decrement address\n"
1760     "  /        increment addr by 0x10.  //=0x100, ///=0x1000, etc\n"
1761     "  \\        decrement addr by 0x10.  \\\\=0x100, \\\\\\=0x1000, etc\n"
1762     "  `        clear no-read flag\n"
1763     "  ;        stay at this addr\n"
1764     "  v        change to byte mode\n"
1765     "  w        change to word (2 byte) mode\n"
1766     "  l        change to long (4 byte) mode\n"
1767     "  u        change to doubleword (8 byte) mode\n"
1768     "  m addr   change current addr\n"
1769     "  n        toggle no-read flag\n"
1770     "  r        toggle byte reverse flag\n"
1771     "  < count  back up count bytes\n"
1772     "  > count  skip forward count bytes\n"
1773     "  x        exit this mode\n"
1774     "";
1775 
1776 void
1777 memex(void)
1778 {
1779 	int cmd, inc, i, nslash;
1780 	unsigned long n;
1781 	unsigned char val[16];
1782 
1783 	scanhex((void *)&adrs);
1784 	cmd = skipbl();
1785 	if (cmd == '?') {
1786 		printf(memex_help_string);
1787 		return;
1788 	} else {
1789 		termch = cmd;
1790 	}
1791 	last_cmd = "m\n";
1792 	while ((cmd = skipbl()) != '\n') {
1793 		switch( cmd ){
1794 		case 'b':	size = 1;	break;
1795 		case 'w':	size = 2;	break;
1796 		case 'l':	size = 4;	break;
1797 		case 'd':	size = 8;	break;
1798 		case 'r': 	brev = !brev;	break;
1799 		case 'n':	mnoread = 1;	break;
1800 		case '.':	mnoread = 0;	break;
1801 		}
1802 	}
1803 	if( size <= 0 )
1804 		size = 1;
1805 	else if( size > 8 )
1806 		size = 8;
1807 	for(;;){
1808 		if (!mnoread)
1809 			n = mread(adrs, val, size);
1810 		printf(REG"%c", adrs, brev? 'r': ' ');
1811 		if (!mnoread) {
1812 			if (brev)
1813 				byterev(val, size);
1814 			putchar(' ');
1815 			for (i = 0; i < n; ++i)
1816 				printf("%.2x", val[i]);
1817 			for (; i < size; ++i)
1818 				printf("%s", fault_chars[fault_type]);
1819 		}
1820 		putchar(' ');
1821 		inc = size;
1822 		nslash = 0;
1823 		for(;;){
1824 			if( scanhex(&n) ){
1825 				for (i = 0; i < size; ++i)
1826 					val[i] = n >> (i * 8);
1827 				if (!brev)
1828 					byterev(val, size);
1829 				mwrite(adrs, val, size);
1830 				inc = size;
1831 			}
1832 			cmd = skipbl();
1833 			if (cmd == '\n')
1834 				break;
1835 			inc = 0;
1836 			switch (cmd) {
1837 			case '\'':
1838 				for(;;){
1839 					n = inchar();
1840 					if( n == '\\' )
1841 						n = bsesc();
1842 					else if( n == '\'' )
1843 						break;
1844 					for (i = 0; i < size; ++i)
1845 						val[i] = n >> (i * 8);
1846 					if (!brev)
1847 						byterev(val, size);
1848 					mwrite(adrs, val, size);
1849 					adrs += size;
1850 				}
1851 				adrs -= size;
1852 				inc = size;
1853 				break;
1854 			case ',':
1855 				adrs += size;
1856 				break;
1857 			case '.':
1858 				mnoread = 0;
1859 				break;
1860 			case ';':
1861 				break;
1862 			case 'x':
1863 			case EOF:
1864 				scannl();
1865 				return;
1866 			case 'b':
1867 			case 'v':
1868 				size = 1;
1869 				break;
1870 			case 'w':
1871 				size = 2;
1872 				break;
1873 			case 'l':
1874 				size = 4;
1875 				break;
1876 			case 'u':
1877 				size = 8;
1878 				break;
1879 			case '^':
1880 				adrs -= size;
1881 				break;
1882 				break;
1883 			case '/':
1884 				if (nslash > 0)
1885 					adrs -= 1 << nslash;
1886 				else
1887 					nslash = 0;
1888 				nslash += 4;
1889 				adrs += 1 << nslash;
1890 				break;
1891 			case '\\':
1892 				if (nslash < 0)
1893 					adrs += 1 << -nslash;
1894 				else
1895 					nslash = 0;
1896 				nslash -= 4;
1897 				adrs -= 1 << -nslash;
1898 				break;
1899 			case 'm':
1900 				scanhex((void *)&adrs);
1901 				break;
1902 			case 'n':
1903 				mnoread = 1;
1904 				break;
1905 			case 'r':
1906 				brev = !brev;
1907 				break;
1908 			case '<':
1909 				n = size;
1910 				scanhex(&n);
1911 				adrs -= n;
1912 				break;
1913 			case '>':
1914 				n = size;
1915 				scanhex(&n);
1916 				adrs += n;
1917 				break;
1918 			case '?':
1919 				printf(memex_subcmd_help_string);
1920 				break;
1921 			}
1922 		}
1923 		adrs += inc;
1924 	}
1925 }
1926 
1927 int
1928 bsesc(void)
1929 {
1930 	int c;
1931 
1932 	c = inchar();
1933 	switch( c ){
1934 	case 'n':	c = '\n';	break;
1935 	case 'r':	c = '\r';	break;
1936 	case 'b':	c = '\b';	break;
1937 	case 't':	c = '\t';	break;
1938 	}
1939 	return c;
1940 }
1941 
1942 static void xmon_rawdump (unsigned long adrs, long ndump)
1943 {
1944 	long n, m, r, nr;
1945 	unsigned char temp[16];
1946 
1947 	for (n = ndump; n > 0;) {
1948 		r = n < 16? n: 16;
1949 		nr = mread(adrs, temp, r);
1950 		adrs += nr;
1951 		for (m = 0; m < r; ++m) {
1952 			if (m < nr)
1953 				printf("%.2x", temp[m]);
1954 			else
1955 				printf("%s", fault_chars[fault_type]);
1956 		}
1957 		n -= r;
1958 		if (nr < r)
1959 			break;
1960 	}
1961 	printf("\n");
1962 }
1963 
1964 #define isxdigit(c)	(('0' <= (c) && (c) <= '9') \
1965 			 || ('a' <= (c) && (c) <= 'f') \
1966 			 || ('A' <= (c) && (c) <= 'F'))
1967 void
1968 dump(void)
1969 {
1970 	int c;
1971 
1972 	c = inchar();
1973 	if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
1974 		termch = c;
1975 	scanhex((void *)&adrs);
1976 	if (termch != '\n')
1977 		termch = 0;
1978 	if (c == 'i') {
1979 		scanhex(&nidump);
1980 		if (nidump == 0)
1981 			nidump = 16;
1982 		else if (nidump > MAX_DUMP)
1983 			nidump = MAX_DUMP;
1984 		adrs += ppc_inst_dump(adrs, nidump, 1);
1985 		last_cmd = "di\n";
1986 	} else if (c == 'r') {
1987 		scanhex(&ndump);
1988 		if (ndump == 0)
1989 			ndump = 64;
1990 		xmon_rawdump(adrs, ndump);
1991 		adrs += ndump;
1992 		last_cmd = "dr\n";
1993 	} else {
1994 		scanhex(&ndump);
1995 		if (ndump == 0)
1996 			ndump = 64;
1997 		else if (ndump > MAX_DUMP)
1998 			ndump = MAX_DUMP;
1999 		prdump(adrs, ndump);
2000 		adrs += ndump;
2001 		last_cmd = "d\n";
2002 	}
2003 }
2004 
2005 void
2006 prdump(unsigned long adrs, long ndump)
2007 {
2008 	long n, m, c, r, nr;
2009 	unsigned char temp[16];
2010 
2011 	for (n = ndump; n > 0;) {
2012 		printf(REG, adrs);
2013 		putchar(' ');
2014 		r = n < 16? n: 16;
2015 		nr = mread(adrs, temp, r);
2016 		adrs += nr;
2017 		for (m = 0; m < r; ++m) {
2018 		        if ((m & (sizeof(long) - 1)) == 0 && m > 0)
2019 				putchar(' ');
2020 			if (m < nr)
2021 				printf("%.2x", temp[m]);
2022 			else
2023 				printf("%s", fault_chars[fault_type]);
2024 		}
2025 		for (; m < 16; ++m) {
2026 		        if ((m & (sizeof(long) - 1)) == 0)
2027 				putchar(' ');
2028 			printf("  ");
2029 		}
2030 		printf("  |");
2031 		for (m = 0; m < r; ++m) {
2032 			if (m < nr) {
2033 				c = temp[m];
2034 				putchar(' ' <= c && c <= '~'? c: '.');
2035 			} else
2036 				putchar(' ');
2037 		}
2038 		n -= r;
2039 		for (; m < 16; ++m)
2040 			putchar(' ');
2041 		printf("|\n");
2042 		if (nr < r)
2043 			break;
2044 	}
2045 }
2046 
2047 int
2048 ppc_inst_dump(unsigned long adr, long count, int praddr)
2049 {
2050 	int nr, dotted;
2051 	unsigned long first_adr;
2052 	unsigned long inst, last_inst = 0;
2053 	unsigned char val[4];
2054 
2055 	dotted = 0;
2056 	for (first_adr = adr; count > 0; --count, adr += 4) {
2057 		nr = mread(adr, val, 4);
2058 		if (nr == 0) {
2059 			if (praddr) {
2060 				const char *x = fault_chars[fault_type];
2061 				printf(REG"  %s%s%s%s\n", adr, x, x, x, x);
2062 			}
2063 			break;
2064 		}
2065 		inst = GETWORD(val);
2066 		if (adr > first_adr && inst == last_inst) {
2067 			if (!dotted) {
2068 				printf(" ...\n");
2069 				dotted = 1;
2070 			}
2071 			continue;
2072 		}
2073 		dotted = 0;
2074 		last_inst = inst;
2075 		if (praddr)
2076 			printf(REG"  %.8x", adr, inst);
2077 		printf("\t");
2078 		print_insn_powerpc(inst, adr, 0);	/* always returns 4 */
2079 		printf("\n");
2080 	}
2081 	return adr - first_adr;
2082 }
2083 
2084 void
2085 print_address(unsigned long addr)
2086 {
2087 	xmon_print_symbol(addr, "\t# ", "");
2088 }
2089 
2090 
2091 /*
2092  * Memory operations - move, set, print differences
2093  */
2094 static unsigned long mdest;		/* destination address */
2095 static unsigned long msrc;		/* source address */
2096 static unsigned long mval;		/* byte value to set memory to */
2097 static unsigned long mcount;		/* # bytes to affect */
2098 static unsigned long mdiffs;		/* max # differences to print */
2099 
2100 void
2101 memops(int cmd)
2102 {
2103 	scanhex((void *)&mdest);
2104 	if( termch != '\n' )
2105 		termch = 0;
2106 	scanhex((void *)(cmd == 's'? &mval: &msrc));
2107 	if( termch != '\n' )
2108 		termch = 0;
2109 	scanhex((void *)&mcount);
2110 	switch( cmd ){
2111 	case 'm':
2112 		memmove((void *)mdest, (void *)msrc, mcount);
2113 		break;
2114 	case 's':
2115 		memset((void *)mdest, mval, mcount);
2116 		break;
2117 	case 'd':
2118 		if( termch != '\n' )
2119 			termch = 0;
2120 		scanhex((void *)&mdiffs);
2121 		memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2122 		break;
2123 	}
2124 }
2125 
2126 void
2127 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2128 {
2129 	unsigned n, prt;
2130 
2131 	prt = 0;
2132 	for( n = nb; n > 0; --n )
2133 		if( *p1++ != *p2++ )
2134 			if( ++prt <= maxpr )
2135 				printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2136 					p1[-1], p2 - 1, p2[-1]);
2137 	if( prt > maxpr )
2138 		printf("Total of %d differences\n", prt);
2139 }
2140 
2141 static unsigned mend;
2142 static unsigned mask;
2143 
2144 void
2145 memlocate(void)
2146 {
2147 	unsigned a, n;
2148 	unsigned char val[4];
2149 
2150 	last_cmd = "ml";
2151 	scanhex((void *)&mdest);
2152 	if (termch != '\n') {
2153 		termch = 0;
2154 		scanhex((void *)&mend);
2155 		if (termch != '\n') {
2156 			termch = 0;
2157 			scanhex((void *)&mval);
2158 			mask = ~0;
2159 			if (termch != '\n') termch = 0;
2160 			scanhex((void *)&mask);
2161 		}
2162 	}
2163 	n = 0;
2164 	for (a = mdest; a < mend; a += 4) {
2165 		if (mread(a, val, 4) == 4
2166 			&& ((GETWORD(val) ^ mval) & mask) == 0) {
2167 			printf("%.16x:  %.16x\n", a, GETWORD(val));
2168 			if (++n >= 10)
2169 				break;
2170 		}
2171 	}
2172 }
2173 
2174 static unsigned long mskip = 0x1000;
2175 static unsigned long mlim = 0xffffffff;
2176 
2177 void
2178 memzcan(void)
2179 {
2180 	unsigned char v;
2181 	unsigned a;
2182 	int ok, ook;
2183 
2184 	scanhex(&mdest);
2185 	if (termch != '\n') termch = 0;
2186 	scanhex(&mskip);
2187 	if (termch != '\n') termch = 0;
2188 	scanhex(&mlim);
2189 	ook = 0;
2190 	for (a = mdest; a < mlim; a += mskip) {
2191 		ok = mread(a, &v, 1);
2192 		if (ok && !ook) {
2193 			printf("%.8x .. ", a);
2194 		} else if (!ok && ook)
2195 			printf("%.8x\n", a - mskip);
2196 		ook = ok;
2197 		if (a + mskip < a)
2198 			break;
2199 	}
2200 	if (ook)
2201 		printf("%.8x\n", a - mskip);
2202 }
2203 
2204 void proccall(void)
2205 {
2206 	unsigned long args[8];
2207 	unsigned long ret;
2208 	int i;
2209 	typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2210 			unsigned long, unsigned long, unsigned long,
2211 			unsigned long, unsigned long, unsigned long);
2212 	callfunc_t func;
2213 
2214 	if (!scanhex(&adrs))
2215 		return;
2216 	if (termch != '\n')
2217 		termch = 0;
2218 	for (i = 0; i < 8; ++i)
2219 		args[i] = 0;
2220 	for (i = 0; i < 8; ++i) {
2221 		if (!scanhex(&args[i]) || termch == '\n')
2222 			break;
2223 		termch = 0;
2224 	}
2225 	func = (callfunc_t) adrs;
2226 	ret = 0;
2227 	if (setjmp(bus_error_jmp) == 0) {
2228 		catch_memory_errors = 1;
2229 		sync();
2230 		ret = func(args[0], args[1], args[2], args[3],
2231 			   args[4], args[5], args[6], args[7]);
2232 		sync();
2233 		printf("return value is %x\n", ret);
2234 	} else {
2235 		printf("*** %x exception occurred\n", fault_except);
2236 	}
2237 	catch_memory_errors = 0;
2238 }
2239 
2240 /* Input scanning routines */
2241 int
2242 skipbl(void)
2243 {
2244 	int c;
2245 
2246 	if( termch != 0 ){
2247 		c = termch;
2248 		termch = 0;
2249 	} else
2250 		c = inchar();
2251 	while( c == ' ' || c == '\t' )
2252 		c = inchar();
2253 	return c;
2254 }
2255 
2256 #define N_PTREGS	44
2257 static char *regnames[N_PTREGS] = {
2258 	"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2259 	"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2260 	"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2261 	"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2262 	"pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2263 #ifdef CONFIG_PPC64
2264 	"softe",
2265 #else
2266 	"mq",
2267 #endif
2268 	"trap", "dar", "dsisr", "res"
2269 };
2270 
2271 int
2272 scanhex(unsigned long *vp)
2273 {
2274 	int c, d;
2275 	unsigned long v;
2276 
2277 	c = skipbl();
2278 	if (c == '%') {
2279 		/* parse register name */
2280 		char regname[8];
2281 		int i;
2282 
2283 		for (i = 0; i < sizeof(regname) - 1; ++i) {
2284 			c = inchar();
2285 			if (!isalnum(c)) {
2286 				termch = c;
2287 				break;
2288 			}
2289 			regname[i] = c;
2290 		}
2291 		regname[i] = 0;
2292 		for (i = 0; i < N_PTREGS; ++i) {
2293 			if (strcmp(regnames[i], regname) == 0) {
2294 				if (xmon_regs == NULL) {
2295 					printf("regs not available\n");
2296 					return 0;
2297 				}
2298 				*vp = ((unsigned long *)xmon_regs)[i];
2299 				return 1;
2300 			}
2301 		}
2302 		printf("invalid register name '%%%s'\n", regname);
2303 		return 0;
2304 	}
2305 
2306 	/* skip leading "0x" if any */
2307 
2308 	if (c == '0') {
2309 		c = inchar();
2310 		if (c == 'x') {
2311 			c = inchar();
2312 		} else {
2313 			d = hexdigit(c);
2314 			if (d == EOF) {
2315 				termch = c;
2316 				*vp = 0;
2317 				return 1;
2318 			}
2319 		}
2320 	} else if (c == '$') {
2321 		int i;
2322 		for (i=0; i<63; i++) {
2323 			c = inchar();
2324 			if (isspace(c)) {
2325 				termch = c;
2326 				break;
2327 			}
2328 			tmpstr[i] = c;
2329 		}
2330 		tmpstr[i++] = 0;
2331 		*vp = 0;
2332 		if (setjmp(bus_error_jmp) == 0) {
2333 			catch_memory_errors = 1;
2334 			sync();
2335 			*vp = kallsyms_lookup_name(tmpstr);
2336 			sync();
2337 		}
2338 		catch_memory_errors = 0;
2339 		if (!(*vp)) {
2340 			printf("unknown symbol '%s'\n", tmpstr);
2341 			return 0;
2342 		}
2343 		return 1;
2344 	}
2345 
2346 	d = hexdigit(c);
2347 	if (d == EOF) {
2348 		termch = c;
2349 		return 0;
2350 	}
2351 	v = 0;
2352 	do {
2353 		v = (v << 4) + d;
2354 		c = inchar();
2355 		d = hexdigit(c);
2356 	} while (d != EOF);
2357 	termch = c;
2358 	*vp = v;
2359 	return 1;
2360 }
2361 
2362 void
2363 scannl(void)
2364 {
2365 	int c;
2366 
2367 	c = termch;
2368 	termch = 0;
2369 	while( c != '\n' )
2370 		c = inchar();
2371 }
2372 
2373 int hexdigit(int c)
2374 {
2375 	if( '0' <= c && c <= '9' )
2376 		return c - '0';
2377 	if( 'A' <= c && c <= 'F' )
2378 		return c - ('A' - 10);
2379 	if( 'a' <= c && c <= 'f' )
2380 		return c - ('a' - 10);
2381 	return EOF;
2382 }
2383 
2384 void
2385 getstring(char *s, int size)
2386 {
2387 	int c;
2388 
2389 	c = skipbl();
2390 	do {
2391 		if( size > 1 ){
2392 			*s++ = c;
2393 			--size;
2394 		}
2395 		c = inchar();
2396 	} while( c != ' ' && c != '\t' && c != '\n' );
2397 	termch = c;
2398 	*s = 0;
2399 }
2400 
2401 static char line[256];
2402 static char *lineptr;
2403 
2404 void
2405 flush_input(void)
2406 {
2407 	lineptr = NULL;
2408 }
2409 
2410 int
2411 inchar(void)
2412 {
2413 	if (lineptr == NULL || *lineptr == 0) {
2414 		if (xmon_gets(line, sizeof(line)) == NULL) {
2415 			lineptr = NULL;
2416 			return EOF;
2417 		}
2418 		lineptr = line;
2419 	}
2420 	return *lineptr++;
2421 }
2422 
2423 void
2424 take_input(char *str)
2425 {
2426 	lineptr = str;
2427 }
2428 
2429 
2430 static void
2431 symbol_lookup(void)
2432 {
2433 	int type = inchar();
2434 	unsigned long addr;
2435 	static char tmp[64];
2436 
2437 	switch (type) {
2438 	case 'a':
2439 		if (scanhex(&addr))
2440 			xmon_print_symbol(addr, ": ", "\n");
2441 		termch = 0;
2442 		break;
2443 	case 's':
2444 		getstring(tmp, 64);
2445 		if (setjmp(bus_error_jmp) == 0) {
2446 			catch_memory_errors = 1;
2447 			sync();
2448 			addr = kallsyms_lookup_name(tmp);
2449 			if (addr)
2450 				printf("%s: %lx\n", tmp, addr);
2451 			else
2452 				printf("Symbol '%s' not found.\n", tmp);
2453 			sync();
2454 		}
2455 		catch_memory_errors = 0;
2456 		termch = 0;
2457 		break;
2458 	}
2459 }
2460 
2461 
2462 /* Print an address in numeric and symbolic form (if possible) */
2463 static void xmon_print_symbol(unsigned long address, const char *mid,
2464 			      const char *after)
2465 {
2466 	char *modname;
2467 	const char *name = NULL;
2468 	unsigned long offset, size;
2469 
2470 	printf(REG, address);
2471 	if (setjmp(bus_error_jmp) == 0) {
2472 		catch_memory_errors = 1;
2473 		sync();
2474 		name = kallsyms_lookup(address, &size, &offset, &modname,
2475 				       tmpstr);
2476 		sync();
2477 		/* wait a little while to see if we get a machine check */
2478 		__delay(200);
2479 	}
2480 
2481 	catch_memory_errors = 0;
2482 
2483 	if (name) {
2484 		printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2485 		if (modname)
2486 			printf(" [%s]", modname);
2487 	}
2488 	printf("%s", after);
2489 }
2490 
2491 #ifdef CONFIG_PPC64
2492 static void dump_slb(void)
2493 {
2494 	int i;
2495 	unsigned long tmp;
2496 
2497 	printf("SLB contents of cpu %x\n", smp_processor_id());
2498 
2499 	for (i = 0; i < SLB_NUM_ENTRIES; i++) {
2500 		asm volatile("slbmfee  %0,%1" : "=r" (tmp) : "r" (i));
2501 		printf("%02d %016lx ", i, tmp);
2502 
2503 		asm volatile("slbmfev  %0,%1" : "=r" (tmp) : "r" (i));
2504 		printf("%016lx\n", tmp);
2505 	}
2506 }
2507 
2508 static void dump_stab(void)
2509 {
2510 	int i;
2511 	unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2512 
2513 	printf("Segment table contents of cpu %x\n", smp_processor_id());
2514 
2515 	for (i = 0; i < PAGE_SIZE/16; i++) {
2516 		unsigned long a, b;
2517 
2518 		a = *tmp++;
2519 		b = *tmp++;
2520 
2521 		if (a || b) {
2522 			printf("%03d %016lx ", i, a);
2523 			printf("%016lx\n", b);
2524 		}
2525 	}
2526 }
2527 
2528 void dump_segments(void)
2529 {
2530 	if (cpu_has_feature(CPU_FTR_SLB))
2531 		dump_slb();
2532 	else
2533 		dump_stab();
2534 }
2535 #endif
2536 
2537 #ifdef CONFIG_PPC_STD_MMU_32
2538 void dump_segments(void)
2539 {
2540 	int i;
2541 
2542 	printf("sr0-15 =");
2543 	for (i = 0; i < 16; ++i)
2544 		printf(" %x", mfsrin(i));
2545 	printf("\n");
2546 }
2547 #endif
2548 
2549 void xmon_init(int enable)
2550 {
2551 	if (enable) {
2552 		__debugger = xmon;
2553 		__debugger_ipi = xmon_ipi;
2554 		__debugger_bpt = xmon_bpt;
2555 		__debugger_sstep = xmon_sstep;
2556 		__debugger_iabr_match = xmon_iabr_match;
2557 		__debugger_dabr_match = xmon_dabr_match;
2558 		__debugger_fault_handler = xmon_fault_handler;
2559 	} else {
2560 		__debugger = NULL;
2561 		__debugger_ipi = NULL;
2562 		__debugger_bpt = NULL;
2563 		__debugger_sstep = NULL;
2564 		__debugger_iabr_match = NULL;
2565 		__debugger_dabr_match = NULL;
2566 		__debugger_fault_handler = NULL;
2567 	}
2568 	xmon_map_scc();
2569 }
2570 
2571 #ifdef CONFIG_MAGIC_SYSRQ
2572 static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs,
2573 			      struct tty_struct *tty)
2574 {
2575 	/* ensure xmon is enabled */
2576 	xmon_init(1);
2577 	debugger(pt_regs);
2578 }
2579 
2580 static struct sysrq_key_op sysrq_xmon_op =
2581 {
2582 	.handler =	sysrq_handle_xmon,
2583 	.help_msg =	"Xmon",
2584 	.action_msg =	"Entering xmon",
2585 };
2586 
2587 static int __init setup_xmon_sysrq(void)
2588 {
2589 	register_sysrq_key('x', &sysrq_xmon_op);
2590 	return 0;
2591 }
2592 __initcall(setup_xmon_sysrq);
2593 #endif /* CONFIG_MAGIC_SYSRQ */
2594