xref: /linux/arch/powerpc/xmon/xmon.c (revision 9ce7677cfd7cd871adb457c80bea3b581b839641)
1 /*
2  * Routines providing a simple monitor for use on the PowerMac.
3  *
4  * Copyright (C) 1996-2005 Paul Mackerras.
5  *
6  *      This program is free software; you can redistribute it and/or
7  *      modify it under the terms of the GNU General Public License
8  *      as published by the Free Software Foundation; either version
9  *      2 of the License, or (at your option) any later version.
10  */
11 #include <linux/config.h>
12 #include <linux/errno.h>
13 #include <linux/sched.h>
14 #include <linux/smp.h>
15 #include <linux/mm.h>
16 #include <linux/reboot.h>
17 #include <linux/delay.h>
18 #include <linux/kallsyms.h>
19 #include <linux/cpumask.h>
20 #include <linux/module.h>
21 #include <linux/sysrq.h>
22 #include <linux/interrupt.h>
23 
24 #include <asm/ptrace.h>
25 #include <asm/string.h>
26 #include <asm/prom.h>
27 #include <asm/machdep.h>
28 #include <asm/xmon.h>
29 #ifdef CONFIG_PMAC_BACKLIGHT
30 #include <asm/backlight.h>
31 #endif
32 #include <asm/processor.h>
33 #include <asm/pgtable.h>
34 #include <asm/mmu.h>
35 #include <asm/mmu_context.h>
36 #include <asm/cputable.h>
37 #include <asm/rtas.h>
38 #include <asm/sstep.h>
39 #include <asm/bug.h>
40 
41 #ifdef CONFIG_PPC64
42 #include <asm/hvcall.h>
43 #include <asm/paca.h>
44 #endif
45 
46 #include "nonstdio.h"
47 
48 #define scanhex	xmon_scanhex
49 #define skipbl	xmon_skipbl
50 
51 #ifdef CONFIG_SMP
52 cpumask_t cpus_in_xmon = CPU_MASK_NONE;
53 static unsigned long xmon_taken = 1;
54 static int xmon_owner;
55 static int xmon_gate;
56 #endif /* CONFIG_SMP */
57 
58 static unsigned long in_xmon = 0;
59 
60 static unsigned long adrs;
61 static int size = 1;
62 #define MAX_DUMP (128 * 1024)
63 static unsigned long ndump = 64;
64 static unsigned long nidump = 16;
65 static unsigned long ncsum = 4096;
66 static int termch;
67 static char tmpstr[128];
68 
69 #define JMP_BUF_LEN	23
70 static long bus_error_jmp[JMP_BUF_LEN];
71 static int catch_memory_errors;
72 static long *xmon_fault_jmp[NR_CPUS];
73 #define setjmp xmon_setjmp
74 #define longjmp xmon_longjmp
75 
76 /* Breakpoint stuff */
77 struct bpt {
78 	unsigned long	address;
79 	unsigned int	instr[2];
80 	atomic_t	ref_count;
81 	int		enabled;
82 	unsigned long	pad;
83 };
84 
85 /* Bits in bpt.enabled */
86 #define BP_IABR_TE	1		/* IABR translation enabled */
87 #define BP_IABR		2
88 #define BP_TRAP		8
89 #define BP_DABR		0x10
90 
91 #define NBPTS	256
92 static struct bpt bpts[NBPTS];
93 static struct bpt dabr;
94 static struct bpt *iabr;
95 static unsigned bpinstr = 0x7fe00008;	/* trap */
96 
97 #define BP_NUM(bp)	((bp) - bpts + 1)
98 
99 /* Prototypes */
100 static int cmds(struct pt_regs *);
101 static int mread(unsigned long, void *, int);
102 static int mwrite(unsigned long, void *, int);
103 static int handle_fault(struct pt_regs *);
104 static void byterev(unsigned char *, int);
105 static void memex(void);
106 static int bsesc(void);
107 static void dump(void);
108 static void prdump(unsigned long, long);
109 static int ppc_inst_dump(unsigned long, long, int);
110 void print_address(unsigned long);
111 static void backtrace(struct pt_regs *);
112 static void excprint(struct pt_regs *);
113 static void prregs(struct pt_regs *);
114 static void memops(int);
115 static void memlocate(void);
116 static void memzcan(void);
117 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
118 int skipbl(void);
119 int scanhex(unsigned long *valp);
120 static void scannl(void);
121 static int hexdigit(int);
122 void getstring(char *, int);
123 static void flush_input(void);
124 static int inchar(void);
125 static void take_input(char *);
126 static unsigned long read_spr(int);
127 static void write_spr(int, unsigned long);
128 static void super_regs(void);
129 static void remove_bpts(void);
130 static void insert_bpts(void);
131 static void remove_cpu_bpts(void);
132 static void insert_cpu_bpts(void);
133 static struct bpt *at_breakpoint(unsigned long pc);
134 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
135 static int  do_step(struct pt_regs *);
136 static void bpt_cmds(void);
137 static void cacheflush(void);
138 static int  cpu_cmd(void);
139 static void csum(void);
140 static void bootcmds(void);
141 static void proccall(void);
142 void dump_segments(void);
143 static void symbol_lookup(void);
144 static void xmon_print_symbol(unsigned long address, const char *mid,
145 			      const char *after);
146 static const char *getvecname(unsigned long vec);
147 
148 extern int print_insn_powerpc(unsigned long, unsigned long, int);
149 
150 extern void xmon_enter(void);
151 extern void xmon_leave(void);
152 
153 extern long setjmp(long *);
154 extern void longjmp(long *, long);
155 extern void xmon_save_regs(struct pt_regs *);
156 
157 #ifdef CONFIG_PPC64
158 #define REG		"%.16lx"
159 #define REGS_PER_LINE	4
160 #define LAST_VOLATILE	13
161 #else
162 #define REG		"%.8lx"
163 #define REGS_PER_LINE	8
164 #define LAST_VOLATILE	12
165 #endif
166 
167 #define GETWORD(v)	(((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
168 
169 #define isxdigit(c)	(('0' <= (c) && (c) <= '9') \
170 			 || ('a' <= (c) && (c) <= 'f') \
171 			 || ('A' <= (c) && (c) <= 'F'))
172 #define isalnum(c)	(('0' <= (c) && (c) <= '9') \
173 			 || ('a' <= (c) && (c) <= 'z') \
174 			 || ('A' <= (c) && (c) <= 'Z'))
175 #define isspace(c)	(c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
176 
177 static char *help_string = "\
178 Commands:\n\
179   b	show breakpoints\n\
180   bd	set data breakpoint\n\
181   bi	set instruction breakpoint\n\
182   bc	clear breakpoint\n"
183 #ifdef CONFIG_SMP
184   "\
185   c	print cpus stopped in xmon\n\
186   c#	try to switch to cpu number h (in hex)\n"
187 #endif
188   "\
189   C	checksum\n\
190   d	dump bytes\n\
191   di	dump instructions\n\
192   df	dump float values\n\
193   dd	dump double values\n\
194   e	print exception information\n\
195   f	flush cache\n\
196   la	lookup symbol+offset of specified address\n\
197   ls	lookup address of specified symbol\n\
198   m	examine/change memory\n\
199   mm	move a block of memory\n\
200   ms	set a block of memory\n\
201   md	compare two blocks of memory\n\
202   ml	locate a block of memory\n\
203   mz	zero a block of memory\n\
204   mi	show information about memory allocation\n\
205   p 	call a procedure\n\
206   r	print registers\n\
207   s	single step\n\
208   S	print special registers\n\
209   t	print backtrace\n\
210   x	exit monitor and recover\n\
211   X	exit monitor and dont recover\n"
212 #ifdef CONFIG_PPC64
213 "  u	dump segment table or SLB\n"
214 #endif
215 #ifdef CONFIG_PPC_STD_MMU_32
216 "  u	dump segment registers\n"
217 #endif
218 "  ?	help\n"
219 "  zr	reboot\n\
220   zh	halt\n"
221 ;
222 
223 static struct pt_regs *xmon_regs;
224 
225 static inline void sync(void)
226 {
227 	asm volatile("sync; isync");
228 }
229 
230 static inline void store_inst(void *p)
231 {
232 	asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
233 }
234 
235 static inline void cflush(void *p)
236 {
237 	asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
238 }
239 
240 static inline void cinval(void *p)
241 {
242 	asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
243 }
244 
245 /*
246  * Disable surveillance (the service processor watchdog function)
247  * while we are in xmon.
248  * XXX we should re-enable it when we leave. :)
249  */
250 #define SURVEILLANCE_TOKEN	9000
251 
252 static inline void disable_surveillance(void)
253 {
254 #ifdef CONFIG_PPC_PSERIES
255 	/* Since this can't be a module, args should end up below 4GB. */
256 	static struct rtas_args args;
257 
258 	/*
259 	 * At this point we have got all the cpus we can into
260 	 * xmon, so there is hopefully no other cpu calling RTAS
261 	 * at the moment, even though we don't take rtas.lock.
262 	 * If we did try to take rtas.lock there would be a
263 	 * real possibility of deadlock.
264 	 */
265 	args.token = rtas_token("set-indicator");
266 	if (args.token == RTAS_UNKNOWN_SERVICE)
267 		return;
268 	args.nargs = 3;
269 	args.nret = 1;
270 	args.rets = &args.args[3];
271 	args.args[0] = SURVEILLANCE_TOKEN;
272 	args.args[1] = 0;
273 	args.args[2] = 0;
274 	enter_rtas(__pa(&args));
275 #endif /* CONFIG_PPC_PSERIES */
276 }
277 
278 #ifdef CONFIG_SMP
279 static int xmon_speaker;
280 
281 static void get_output_lock(void)
282 {
283 	int me = smp_processor_id() + 0x100;
284 	int last_speaker = 0, prev;
285 	long timeout;
286 
287 	if (xmon_speaker == me)
288 		return;
289 	for (;;) {
290 		if (xmon_speaker == 0) {
291 			last_speaker = cmpxchg(&xmon_speaker, 0, me);
292 			if (last_speaker == 0)
293 				return;
294 		}
295 		timeout = 10000000;
296 		while (xmon_speaker == last_speaker) {
297 			if (--timeout > 0)
298 				continue;
299 			/* hostile takeover */
300 			prev = cmpxchg(&xmon_speaker, last_speaker, me);
301 			if (prev == last_speaker)
302 				return;
303 			break;
304 		}
305 	}
306 }
307 
308 static void release_output_lock(void)
309 {
310 	xmon_speaker = 0;
311 }
312 #endif
313 
314 int xmon_core(struct pt_regs *regs, int fromipi)
315 {
316 	int cmd = 0;
317 	unsigned long msr;
318 	struct bpt *bp;
319 	long recurse_jmp[JMP_BUF_LEN];
320 	unsigned long offset;
321 #ifdef CONFIG_SMP
322 	int cpu;
323 	int secondary;
324 	unsigned long timeout;
325 #endif
326 
327 	msr = mfmsr();
328 	mtmsr(msr & ~MSR_EE);	/* disable interrupts */
329 
330 	bp = in_breakpoint_table(regs->nip, &offset);
331 	if (bp != NULL) {
332 		regs->nip = bp->address + offset;
333 		atomic_dec(&bp->ref_count);
334 	}
335 
336 	remove_cpu_bpts();
337 
338 #ifdef CONFIG_SMP
339 	cpu = smp_processor_id();
340 	if (cpu_isset(cpu, cpus_in_xmon)) {
341 		get_output_lock();
342 		excprint(regs);
343 		printf("cpu 0x%x: Exception %lx %s in xmon, "
344 		       "returning to main loop\n",
345 		       cpu, regs->trap, getvecname(TRAP(regs)));
346 		release_output_lock();
347 		longjmp(xmon_fault_jmp[cpu], 1);
348 	}
349 
350 	if (setjmp(recurse_jmp) != 0) {
351 		if (!in_xmon || !xmon_gate) {
352 			get_output_lock();
353 			printf("xmon: WARNING: bad recursive fault "
354 			       "on cpu 0x%x\n", cpu);
355 			release_output_lock();
356 			goto waiting;
357 		}
358 		secondary = !(xmon_taken && cpu == xmon_owner);
359 		goto cmdloop;
360 	}
361 
362 	xmon_fault_jmp[cpu] = recurse_jmp;
363 	cpu_set(cpu, cpus_in_xmon);
364 
365 	bp = NULL;
366 	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
367 		bp = at_breakpoint(regs->nip);
368 	if (bp || (regs->msr & MSR_RI) == 0)
369 		fromipi = 0;
370 
371 	if (!fromipi) {
372 		get_output_lock();
373 		excprint(regs);
374 		if (bp) {
375 			printf("cpu 0x%x stopped at breakpoint 0x%x (",
376 			       cpu, BP_NUM(bp));
377 			xmon_print_symbol(regs->nip, " ", ")\n");
378 		}
379 		if ((regs->msr & MSR_RI) == 0)
380 			printf("WARNING: exception is not recoverable, "
381 			       "can't continue\n");
382 		release_output_lock();
383 	}
384 
385  waiting:
386 	secondary = 1;
387 	while (secondary && !xmon_gate) {
388 		if (in_xmon == 0) {
389 			if (fromipi)
390 				goto leave;
391 			secondary = test_and_set_bit(0, &in_xmon);
392 		}
393 		barrier();
394 	}
395 
396 	if (!secondary && !xmon_gate) {
397 		/* we are the first cpu to come in */
398 		/* interrupt other cpu(s) */
399 		int ncpus = num_online_cpus();
400 
401 		xmon_owner = cpu;
402 		mb();
403 		if (ncpus > 1) {
404 			smp_send_debugger_break(MSG_ALL_BUT_SELF);
405 			/* wait for other cpus to come in */
406 			for (timeout = 100000000; timeout != 0; --timeout) {
407 				if (cpus_weight(cpus_in_xmon) >= ncpus)
408 					break;
409 				barrier();
410 			}
411 		}
412 		remove_bpts();
413 		disable_surveillance();
414 		/* for breakpoint or single step, print the current instr. */
415 		if (bp || TRAP(regs) == 0xd00)
416 			ppc_inst_dump(regs->nip, 1, 0);
417 		printf("enter ? for help\n");
418 		mb();
419 		xmon_gate = 1;
420 		barrier();
421 	}
422 
423  cmdloop:
424 	while (in_xmon) {
425 		if (secondary) {
426 			if (cpu == xmon_owner) {
427 				if (!test_and_set_bit(0, &xmon_taken)) {
428 					secondary = 0;
429 					continue;
430 				}
431 				/* missed it */
432 				while (cpu == xmon_owner)
433 					barrier();
434 			}
435 			barrier();
436 		} else {
437 			cmd = cmds(regs);
438 			if (cmd != 0) {
439 				/* exiting xmon */
440 				insert_bpts();
441 				xmon_gate = 0;
442 				wmb();
443 				in_xmon = 0;
444 				break;
445 			}
446 			/* have switched to some other cpu */
447 			secondary = 1;
448 		}
449 	}
450  leave:
451 	cpu_clear(cpu, cpus_in_xmon);
452 	xmon_fault_jmp[cpu] = NULL;
453 
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 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 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 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 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 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 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 		case EOF:
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 (addr < KERNELBASE) {
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 (dabr.address < KERNELBASE) {
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 #define isxdigit(c)	(('0' <= (c) && (c) <= '9') \
1940 			 || ('a' <= (c) && (c) <= 'f') \
1941 			 || ('A' <= (c) && (c) <= 'F'))
1942 void
1943 dump(void)
1944 {
1945 	int c;
1946 
1947 	c = inchar();
1948 	if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
1949 		termch = c;
1950 	scanhex((void *)&adrs);
1951 	if (termch != '\n')
1952 		termch = 0;
1953 	if (c == 'i') {
1954 		scanhex(&nidump);
1955 		if (nidump == 0)
1956 			nidump = 16;
1957 		else if (nidump > MAX_DUMP)
1958 			nidump = MAX_DUMP;
1959 		adrs += ppc_inst_dump(adrs, nidump, 1);
1960 		last_cmd = "di\n";
1961 	} else {
1962 		scanhex(&ndump);
1963 		if (ndump == 0)
1964 			ndump = 64;
1965 		else if (ndump > MAX_DUMP)
1966 			ndump = MAX_DUMP;
1967 		prdump(adrs, ndump);
1968 		adrs += ndump;
1969 		last_cmd = "d\n";
1970 	}
1971 }
1972 
1973 void
1974 prdump(unsigned long adrs, long ndump)
1975 {
1976 	long n, m, c, r, nr;
1977 	unsigned char temp[16];
1978 
1979 	for (n = ndump; n > 0;) {
1980 		printf(REG, adrs);
1981 		putchar(' ');
1982 		r = n < 16? n: 16;
1983 		nr = mread(adrs, temp, r);
1984 		adrs += nr;
1985 		for (m = 0; m < r; ++m) {
1986 		        if ((m & (sizeof(long) - 1)) == 0 && m > 0)
1987 				putchar(' ');
1988 			if (m < nr)
1989 				printf("%.2x", temp[m]);
1990 			else
1991 				printf("%s", fault_chars[fault_type]);
1992 		}
1993 		for (; m < 16; ++m) {
1994 		        if ((m & (sizeof(long) - 1)) == 0)
1995 				putchar(' ');
1996 			printf("  ");
1997 		}
1998 		printf("  |");
1999 		for (m = 0; m < r; ++m) {
2000 			if (m < nr) {
2001 				c = temp[m];
2002 				putchar(' ' <= c && c <= '~'? c: '.');
2003 			} else
2004 				putchar(' ');
2005 		}
2006 		n -= r;
2007 		for (; m < 16; ++m)
2008 			putchar(' ');
2009 		printf("|\n");
2010 		if (nr < r)
2011 			break;
2012 	}
2013 }
2014 
2015 int
2016 ppc_inst_dump(unsigned long adr, long count, int praddr)
2017 {
2018 	int nr, dotted;
2019 	unsigned long first_adr;
2020 	unsigned long inst, last_inst = 0;
2021 	unsigned char val[4];
2022 
2023 	dotted = 0;
2024 	for (first_adr = adr; count > 0; --count, adr += 4) {
2025 		nr = mread(adr, val, 4);
2026 		if (nr == 0) {
2027 			if (praddr) {
2028 				const char *x = fault_chars[fault_type];
2029 				printf(REG"  %s%s%s%s\n", adr, x, x, x, x);
2030 			}
2031 			break;
2032 		}
2033 		inst = GETWORD(val);
2034 		if (adr > first_adr && inst == last_inst) {
2035 			if (!dotted) {
2036 				printf(" ...\n");
2037 				dotted = 1;
2038 			}
2039 			continue;
2040 		}
2041 		dotted = 0;
2042 		last_inst = inst;
2043 		if (praddr)
2044 			printf(REG"  %.8x", adr, inst);
2045 		printf("\t");
2046 		print_insn_powerpc(inst, adr, 0);	/* always returns 4 */
2047 		printf("\n");
2048 	}
2049 	return adr - first_adr;
2050 }
2051 
2052 void
2053 print_address(unsigned long addr)
2054 {
2055 	xmon_print_symbol(addr, "\t# ", "");
2056 }
2057 
2058 
2059 /*
2060  * Memory operations - move, set, print differences
2061  */
2062 static unsigned long mdest;		/* destination address */
2063 static unsigned long msrc;		/* source address */
2064 static unsigned long mval;		/* byte value to set memory to */
2065 static unsigned long mcount;		/* # bytes to affect */
2066 static unsigned long mdiffs;		/* max # differences to print */
2067 
2068 void
2069 memops(int cmd)
2070 {
2071 	scanhex((void *)&mdest);
2072 	if( termch != '\n' )
2073 		termch = 0;
2074 	scanhex((void *)(cmd == 's'? &mval: &msrc));
2075 	if( termch != '\n' )
2076 		termch = 0;
2077 	scanhex((void *)&mcount);
2078 	switch( cmd ){
2079 	case 'm':
2080 		memmove((void *)mdest, (void *)msrc, mcount);
2081 		break;
2082 	case 's':
2083 		memset((void *)mdest, mval, mcount);
2084 		break;
2085 	case 'd':
2086 		if( termch != '\n' )
2087 			termch = 0;
2088 		scanhex((void *)&mdiffs);
2089 		memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2090 		break;
2091 	}
2092 }
2093 
2094 void
2095 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2096 {
2097 	unsigned n, prt;
2098 
2099 	prt = 0;
2100 	for( n = nb; n > 0; --n )
2101 		if( *p1++ != *p2++ )
2102 			if( ++prt <= maxpr )
2103 				printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2104 					p1[-1], p2 - 1, p2[-1]);
2105 	if( prt > maxpr )
2106 		printf("Total of %d differences\n", prt);
2107 }
2108 
2109 static unsigned mend;
2110 static unsigned mask;
2111 
2112 void
2113 memlocate(void)
2114 {
2115 	unsigned a, n;
2116 	unsigned char val[4];
2117 
2118 	last_cmd = "ml";
2119 	scanhex((void *)&mdest);
2120 	if (termch != '\n') {
2121 		termch = 0;
2122 		scanhex((void *)&mend);
2123 		if (termch != '\n') {
2124 			termch = 0;
2125 			scanhex((void *)&mval);
2126 			mask = ~0;
2127 			if (termch != '\n') termch = 0;
2128 			scanhex((void *)&mask);
2129 		}
2130 	}
2131 	n = 0;
2132 	for (a = mdest; a < mend; a += 4) {
2133 		if (mread(a, val, 4) == 4
2134 			&& ((GETWORD(val) ^ mval) & mask) == 0) {
2135 			printf("%.16x:  %.16x\n", a, GETWORD(val));
2136 			if (++n >= 10)
2137 				break;
2138 		}
2139 	}
2140 }
2141 
2142 static unsigned long mskip = 0x1000;
2143 static unsigned long mlim = 0xffffffff;
2144 
2145 void
2146 memzcan(void)
2147 {
2148 	unsigned char v;
2149 	unsigned a;
2150 	int ok, ook;
2151 
2152 	scanhex(&mdest);
2153 	if (termch != '\n') termch = 0;
2154 	scanhex(&mskip);
2155 	if (termch != '\n') termch = 0;
2156 	scanhex(&mlim);
2157 	ook = 0;
2158 	for (a = mdest; a < mlim; a += mskip) {
2159 		ok = mread(a, &v, 1);
2160 		if (ok && !ook) {
2161 			printf("%.8x .. ", a);
2162 		} else if (!ok && ook)
2163 			printf("%.8x\n", a - mskip);
2164 		ook = ok;
2165 		if (a + mskip < a)
2166 			break;
2167 	}
2168 	if (ook)
2169 		printf("%.8x\n", a - mskip);
2170 }
2171 
2172 void proccall(void)
2173 {
2174 	unsigned long args[8];
2175 	unsigned long ret;
2176 	int i;
2177 	typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2178 			unsigned long, unsigned long, unsigned long,
2179 			unsigned long, unsigned long, unsigned long);
2180 	callfunc_t func;
2181 
2182 	if (!scanhex(&adrs))
2183 		return;
2184 	if (termch != '\n')
2185 		termch = 0;
2186 	for (i = 0; i < 8; ++i)
2187 		args[i] = 0;
2188 	for (i = 0; i < 8; ++i) {
2189 		if (!scanhex(&args[i]) || termch == '\n')
2190 			break;
2191 		termch = 0;
2192 	}
2193 	func = (callfunc_t) adrs;
2194 	ret = 0;
2195 	if (setjmp(bus_error_jmp) == 0) {
2196 		catch_memory_errors = 1;
2197 		sync();
2198 		ret = func(args[0], args[1], args[2], args[3],
2199 			   args[4], args[5], args[6], args[7]);
2200 		sync();
2201 		printf("return value is %x\n", ret);
2202 	} else {
2203 		printf("*** %x exception occurred\n", fault_except);
2204 	}
2205 	catch_memory_errors = 0;
2206 }
2207 
2208 /* Input scanning routines */
2209 int
2210 skipbl(void)
2211 {
2212 	int c;
2213 
2214 	if( termch != 0 ){
2215 		c = termch;
2216 		termch = 0;
2217 	} else
2218 		c = inchar();
2219 	while( c == ' ' || c == '\t' )
2220 		c = inchar();
2221 	return c;
2222 }
2223 
2224 #define N_PTREGS	44
2225 static char *regnames[N_PTREGS] = {
2226 	"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2227 	"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2228 	"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2229 	"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2230 	"pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2231 #ifdef CONFIG_PPC64
2232 	"softe",
2233 #else
2234 	"mq",
2235 #endif
2236 	"trap", "dar", "dsisr", "res"
2237 };
2238 
2239 int
2240 scanhex(unsigned long *vp)
2241 {
2242 	int c, d;
2243 	unsigned long v;
2244 
2245 	c = skipbl();
2246 	if (c == '%') {
2247 		/* parse register name */
2248 		char regname[8];
2249 		int i;
2250 
2251 		for (i = 0; i < sizeof(regname) - 1; ++i) {
2252 			c = inchar();
2253 			if (!isalnum(c)) {
2254 				termch = c;
2255 				break;
2256 			}
2257 			regname[i] = c;
2258 		}
2259 		regname[i] = 0;
2260 		for (i = 0; i < N_PTREGS; ++i) {
2261 			if (strcmp(regnames[i], regname) == 0) {
2262 				if (xmon_regs == NULL) {
2263 					printf("regs not available\n");
2264 					return 0;
2265 				}
2266 				*vp = ((unsigned long *)xmon_regs)[i];
2267 				return 1;
2268 			}
2269 		}
2270 		printf("invalid register name '%%%s'\n", regname);
2271 		return 0;
2272 	}
2273 
2274 	/* skip leading "0x" if any */
2275 
2276 	if (c == '0') {
2277 		c = inchar();
2278 		if (c == 'x') {
2279 			c = inchar();
2280 		} else {
2281 			d = hexdigit(c);
2282 			if (d == EOF) {
2283 				termch = c;
2284 				*vp = 0;
2285 				return 1;
2286 			}
2287 		}
2288 	} else if (c == '$') {
2289 		int i;
2290 		for (i=0; i<63; i++) {
2291 			c = inchar();
2292 			if (isspace(c)) {
2293 				termch = c;
2294 				break;
2295 			}
2296 			tmpstr[i] = c;
2297 		}
2298 		tmpstr[i++] = 0;
2299 		*vp = 0;
2300 		if (setjmp(bus_error_jmp) == 0) {
2301 			catch_memory_errors = 1;
2302 			sync();
2303 			*vp = kallsyms_lookup_name(tmpstr);
2304 			sync();
2305 		}
2306 		catch_memory_errors = 0;
2307 		if (!(*vp)) {
2308 			printf("unknown symbol '%s'\n", tmpstr);
2309 			return 0;
2310 		}
2311 		return 1;
2312 	}
2313 
2314 	d = hexdigit(c);
2315 	if (d == EOF) {
2316 		termch = c;
2317 		return 0;
2318 	}
2319 	v = 0;
2320 	do {
2321 		v = (v << 4) + d;
2322 		c = inchar();
2323 		d = hexdigit(c);
2324 	} while (d != EOF);
2325 	termch = c;
2326 	*vp = v;
2327 	return 1;
2328 }
2329 
2330 void
2331 scannl(void)
2332 {
2333 	int c;
2334 
2335 	c = termch;
2336 	termch = 0;
2337 	while( c != '\n' )
2338 		c = inchar();
2339 }
2340 
2341 int hexdigit(int c)
2342 {
2343 	if( '0' <= c && c <= '9' )
2344 		return c - '0';
2345 	if( 'A' <= c && c <= 'F' )
2346 		return c - ('A' - 10);
2347 	if( 'a' <= c && c <= 'f' )
2348 		return c - ('a' - 10);
2349 	return EOF;
2350 }
2351 
2352 void
2353 getstring(char *s, int size)
2354 {
2355 	int c;
2356 
2357 	c = skipbl();
2358 	do {
2359 		if( size > 1 ){
2360 			*s++ = c;
2361 			--size;
2362 		}
2363 		c = inchar();
2364 	} while( c != ' ' && c != '\t' && c != '\n' );
2365 	termch = c;
2366 	*s = 0;
2367 }
2368 
2369 static char line[256];
2370 static char *lineptr;
2371 
2372 void
2373 flush_input(void)
2374 {
2375 	lineptr = NULL;
2376 }
2377 
2378 int
2379 inchar(void)
2380 {
2381 	if (lineptr == NULL || *lineptr == 0) {
2382 		if (xmon_gets(line, sizeof(line)) == NULL) {
2383 			lineptr = NULL;
2384 			return EOF;
2385 		}
2386 		lineptr = line;
2387 	}
2388 	return *lineptr++;
2389 }
2390 
2391 void
2392 take_input(char *str)
2393 {
2394 	lineptr = str;
2395 }
2396 
2397 
2398 static void
2399 symbol_lookup(void)
2400 {
2401 	int type = inchar();
2402 	unsigned long addr;
2403 	static char tmp[64];
2404 
2405 	switch (type) {
2406 	case 'a':
2407 		if (scanhex(&addr))
2408 			xmon_print_symbol(addr, ": ", "\n");
2409 		termch = 0;
2410 		break;
2411 	case 's':
2412 		getstring(tmp, 64);
2413 		if (setjmp(bus_error_jmp) == 0) {
2414 			catch_memory_errors = 1;
2415 			sync();
2416 			addr = kallsyms_lookup_name(tmp);
2417 			if (addr)
2418 				printf("%s: %lx\n", tmp, addr);
2419 			else
2420 				printf("Symbol '%s' not found.\n", tmp);
2421 			sync();
2422 		}
2423 		catch_memory_errors = 0;
2424 		termch = 0;
2425 		break;
2426 	}
2427 }
2428 
2429 
2430 /* Print an address in numeric and symbolic form (if possible) */
2431 static void xmon_print_symbol(unsigned long address, const char *mid,
2432 			      const char *after)
2433 {
2434 	char *modname;
2435 	const char *name = NULL;
2436 	unsigned long offset, size;
2437 
2438 	printf(REG, address);
2439 	if (setjmp(bus_error_jmp) == 0) {
2440 		catch_memory_errors = 1;
2441 		sync();
2442 		name = kallsyms_lookup(address, &size, &offset, &modname,
2443 				       tmpstr);
2444 		sync();
2445 		/* wait a little while to see if we get a machine check */
2446 		__delay(200);
2447 	}
2448 
2449 	catch_memory_errors = 0;
2450 
2451 	if (name) {
2452 		printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2453 		if (modname)
2454 			printf(" [%s]", modname);
2455 	}
2456 	printf("%s", after);
2457 }
2458 
2459 #ifdef CONFIG_PPC64
2460 static void dump_slb(void)
2461 {
2462 	int i;
2463 	unsigned long tmp;
2464 
2465 	printf("SLB contents of cpu %x\n", smp_processor_id());
2466 
2467 	for (i = 0; i < SLB_NUM_ENTRIES; i++) {
2468 		asm volatile("slbmfee  %0,%1" : "=r" (tmp) : "r" (i));
2469 		printf("%02d %016lx ", i, tmp);
2470 
2471 		asm volatile("slbmfev  %0,%1" : "=r" (tmp) : "r" (i));
2472 		printf("%016lx\n", tmp);
2473 	}
2474 }
2475 
2476 static void dump_stab(void)
2477 {
2478 	int i;
2479 	unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2480 
2481 	printf("Segment table contents of cpu %x\n", smp_processor_id());
2482 
2483 	for (i = 0; i < PAGE_SIZE/16; i++) {
2484 		unsigned long a, b;
2485 
2486 		a = *tmp++;
2487 		b = *tmp++;
2488 
2489 		if (a || b) {
2490 			printf("%03d %016lx ", i, a);
2491 			printf("%016lx\n", b);
2492 		}
2493 	}
2494 }
2495 
2496 void dump_segments(void)
2497 {
2498 	if (cpu_has_feature(CPU_FTR_SLB))
2499 		dump_slb();
2500 	else
2501 		dump_stab();
2502 }
2503 #endif
2504 
2505 #ifdef CONFIG_PPC_STD_MMU_32
2506 void dump_segments(void)
2507 {
2508 	int i;
2509 
2510 	printf("sr0-15 =");
2511 	for (i = 0; i < 16; ++i)
2512 		printf(" %x", mfsrin(i));
2513 	printf("\n");
2514 }
2515 #endif
2516 
2517 void xmon_init(int enable)
2518 {
2519 	if (enable) {
2520 		__debugger = xmon;
2521 		__debugger_ipi = xmon_ipi;
2522 		__debugger_bpt = xmon_bpt;
2523 		__debugger_sstep = xmon_sstep;
2524 		__debugger_iabr_match = xmon_iabr_match;
2525 		__debugger_dabr_match = xmon_dabr_match;
2526 		__debugger_fault_handler = xmon_fault_handler;
2527 	} else {
2528 		__debugger = NULL;
2529 		__debugger_ipi = NULL;
2530 		__debugger_bpt = NULL;
2531 		__debugger_sstep = NULL;
2532 		__debugger_iabr_match = NULL;
2533 		__debugger_dabr_match = NULL;
2534 		__debugger_fault_handler = NULL;
2535 	}
2536 	xmon_map_scc();
2537 }
2538 
2539 #ifdef CONFIG_MAGIC_SYSRQ
2540 static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs,
2541 			      struct tty_struct *tty)
2542 {
2543 	/* ensure xmon is enabled */
2544 	xmon_init(1);
2545 	debugger(pt_regs);
2546 }
2547 
2548 static struct sysrq_key_op sysrq_xmon_op =
2549 {
2550 	.handler =	sysrq_handle_xmon,
2551 	.help_msg =	"Xmon",
2552 	.action_msg =	"Entering xmon",
2553 };
2554 
2555 static int __init setup_xmon_sysrq(void)
2556 {
2557 	register_sysrq_key('x', &sysrq_xmon_op);
2558 	return 0;
2559 }
2560 __initcall(setup_xmon_sysrq);
2561 #endif /* CONFIG_MAGIC_SYSRQ */
2562