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