1 /*
2  * Routines providing a simple monitor for use on the PowerMac.
3  *
4  * Copyright (C) 1996-2005 Paul Mackerras.
5  * Copyright (C) 2001 PPC64 Team, IBM Corp
6  * Copyrignt (C) 2006 Michael Ellerman, IBM Corp
7  *
8  *      This program is free software; you can redistribute it and/or
9  *      modify it under the terms of the GNU General Public License
10  *      as published by the Free Software Foundation; either version
11  *      2 of the License, or (at your option) any later version.
12  */
13 #include <linux/errno.h>
14 #include <linux/sched.h>
15 #include <linux/smp.h>
16 #include <linux/mm.h>
17 #include <linux/reboot.h>
18 #include <linux/delay.h>
19 #include <linux/kallsyms.h>
20 #include <linux/cpumask.h>
21 #include <linux/module.h>
22 #include <linux/sysrq.h>
23 #include <linux/interrupt.h>
24 #include <linux/irq.h>
25 #include <linux/bug.h>
26 
27 #include <asm/ptrace.h>
28 #include <asm/string.h>
29 #include <asm/prom.h>
30 #include <asm/machdep.h>
31 #include <asm/xmon.h>
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/irq_regs.h>
40 #include <asm/spu.h>
41 #include <asm/spu_priv1.h>
42 #include <asm/firmware.h>
43 #include <asm/setjmp.h>
44 #include <asm/reg.h>
45 
46 #ifdef CONFIG_PPC64
47 #include <asm/hvcall.h>
48 #include <asm/paca.h>
49 #endif
50 
51 #include "nonstdio.h"
52 #include "dis-asm.h"
53 
54 #define scanhex	xmon_scanhex
55 #define skipbl	xmon_skipbl
56 
57 #ifdef CONFIG_SMP
58 static cpumask_t cpus_in_xmon = CPU_MASK_NONE;
59 static unsigned long xmon_taken = 1;
60 static int xmon_owner;
61 static int xmon_gate;
62 #endif /* CONFIG_SMP */
63 
64 static unsigned long in_xmon __read_mostly = 0;
65 
66 static unsigned long adrs;
67 static int size = 1;
68 #define MAX_DUMP (128 * 1024)
69 static unsigned long ndump = 64;
70 static unsigned long nidump = 16;
71 static unsigned long ncsum = 4096;
72 static int termch;
73 static char tmpstr[128];
74 
75 static long bus_error_jmp[JMP_BUF_LEN];
76 static int catch_memory_errors;
77 static long *xmon_fault_jmp[NR_CPUS];
78 
79 /* Breakpoint stuff */
80 struct bpt {
81 	unsigned long	address;
82 	unsigned int	instr[2];
83 	atomic_t	ref_count;
84 	int		enabled;
85 	unsigned long	pad;
86 };
87 
88 /* Bits in bpt.enabled */
89 #define BP_IABR_TE	1		/* IABR translation enabled */
90 #define BP_IABR		2
91 #define BP_TRAP		8
92 #define BP_DABR		0x10
93 
94 #define NBPTS	256
95 static struct bpt bpts[NBPTS];
96 static struct bpt dabr;
97 static struct bpt *iabr;
98 static unsigned bpinstr = 0x7fe00008;	/* trap */
99 
100 #define BP_NUM(bp)	((bp) - bpts + 1)
101 
102 /* Prototypes */
103 static int cmds(struct pt_regs *);
104 static int mread(unsigned long, void *, int);
105 static int mwrite(unsigned long, void *, int);
106 static int handle_fault(struct pt_regs *);
107 static void byterev(unsigned char *, int);
108 static void memex(void);
109 static int bsesc(void);
110 static void dump(void);
111 static void prdump(unsigned long, long);
112 static int ppc_inst_dump(unsigned long, long, int);
113 static void dump_log_buf(void);
114 static void backtrace(struct pt_regs *);
115 static void excprint(struct pt_regs *);
116 static void prregs(struct pt_regs *);
117 static void memops(int);
118 static void memlocate(void);
119 static void memzcan(void);
120 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
121 int skipbl(void);
122 int scanhex(unsigned long *valp);
123 static void scannl(void);
124 static int hexdigit(int);
125 void getstring(char *, int);
126 static void flush_input(void);
127 static int inchar(void);
128 static void take_input(char *);
129 static unsigned long read_spr(int);
130 static void write_spr(int, unsigned long);
131 static void super_regs(void);
132 static void remove_bpts(void);
133 static void insert_bpts(void);
134 static void remove_cpu_bpts(void);
135 static void insert_cpu_bpts(void);
136 static struct bpt *at_breakpoint(unsigned long pc);
137 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
138 static int  do_step(struct pt_regs *);
139 static void bpt_cmds(void);
140 static void cacheflush(void);
141 static int  cpu_cmd(void);
142 static void csum(void);
143 static void bootcmds(void);
144 static void proccall(void);
145 void dump_segments(void);
146 static void symbol_lookup(void);
147 static void xmon_show_stack(unsigned long sp, unsigned long lr,
148 			    unsigned long pc);
149 static void xmon_print_symbol(unsigned long address, const char *mid,
150 			      const char *after);
151 static const char *getvecname(unsigned long vec);
152 
153 static int do_spu_cmd(void);
154 
155 #ifdef CONFIG_44x
156 static void dump_tlb_44x(void);
157 #endif
158 #ifdef CONFIG_PPC_BOOK3E
159 static void dump_tlb_book3e(void);
160 #endif
161 
162 static int xmon_no_auto_backtrace;
163 
164 extern void xmon_enter(void);
165 extern void xmon_leave(void);
166 
167 #ifdef CONFIG_PPC64
168 #define REG		"%.16lx"
169 #define REGS_PER_LINE	4
170 #define LAST_VOLATILE	13
171 #else
172 #define REG		"%.8lx"
173 #define REGS_PER_LINE	8
174 #define LAST_VOLATILE	12
175 #endif
176 
177 #define GETWORD(v)	(((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
178 
179 #define isxdigit(c)	(('0' <= (c) && (c) <= '9') \
180 			 || ('a' <= (c) && (c) <= 'f') \
181 			 || ('A' <= (c) && (c) <= 'F'))
182 #define isalnum(c)	(('0' <= (c) && (c) <= '9') \
183 			 || ('a' <= (c) && (c) <= 'z') \
184 			 || ('A' <= (c) && (c) <= 'Z'))
185 #define isspace(c)	(c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
186 
187 static char *help_string = "\
188 Commands:\n\
189   b	show breakpoints\n\
190   bd	set data breakpoint\n\
191   bi	set instruction breakpoint\n\
192   bc	clear breakpoint\n"
193 #ifdef CONFIG_SMP
194   "\
195   c	print cpus stopped in xmon\n\
196   c#	try to switch to cpu number h (in hex)\n"
197 #endif
198   "\
199   C	checksum\n\
200   d	dump bytes\n\
201   di	dump instructions\n\
202   df	dump float values\n\
203   dd	dump double values\n\
204   dl    dump the kernel log buffer\n\
205   dr	dump stream of raw bytes\n\
206   e	print exception information\n\
207   f	flush cache\n\
208   la	lookup symbol+offset of specified address\n\
209   ls	lookup address of specified symbol\n\
210   m	examine/change memory\n\
211   mm	move a block of memory\n\
212   ms	set a block of memory\n\
213   md	compare two blocks of memory\n\
214   ml	locate a block of memory\n\
215   mz	zero a block of memory\n\
216   mi	show information about memory allocation\n\
217   p 	call a procedure\n\
218   r	print registers\n\
219   s	single step\n"
220 #ifdef CONFIG_SPU_BASE
221 "  ss	stop execution on all spus\n\
222   sr	restore execution on stopped spus\n\
223   sf  #	dump spu fields for spu # (in hex)\n\
224   sd  #	dump spu local store for spu # (in hex)\n\
225   sdi #	disassemble spu local store for spu # (in hex)\n"
226 #endif
227 "  S	print special registers\n\
228   t	print backtrace\n\
229   x	exit monitor and recover\n\
230   X	exit monitor and dont recover\n"
231 #ifdef CONFIG_PPC64
232 "  u	dump segment table or SLB\n"
233 #endif
234 #ifdef CONFIG_PPC_STD_MMU_32
235 "  u	dump segment registers\n"
236 #endif
237 #ifdef CONFIG_44x
238 "  u	dump TLB\n"
239 #endif
240 "  ?	help\n"
241 "  zr	reboot\n\
242   zh	halt\n"
243 ;
244 
245 static struct pt_regs *xmon_regs;
246 
sync(void)247 static inline void sync(void)
248 {
249 	asm volatile("sync; isync");
250 }
251 
store_inst(void * p)252 static inline void store_inst(void *p)
253 {
254 	asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
255 }
256 
cflush(void * p)257 static inline void cflush(void *p)
258 {
259 	asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
260 }
261 
cinval(void * p)262 static inline void cinval(void *p)
263 {
264 	asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
265 }
266 
267 /*
268  * Disable surveillance (the service processor watchdog function)
269  * while we are in xmon.
270  * XXX we should re-enable it when we leave. :)
271  */
272 #define SURVEILLANCE_TOKEN	9000
273 
disable_surveillance(void)274 static inline void disable_surveillance(void)
275 {
276 #ifdef CONFIG_PPC_PSERIES
277 	/* Since this can't be a module, args should end up below 4GB. */
278 	static struct rtas_args args;
279 
280 	/*
281 	 * At this point we have got all the cpus we can into
282 	 * xmon, so there is hopefully no other cpu calling RTAS
283 	 * at the moment, even though we don't take rtas.lock.
284 	 * If we did try to take rtas.lock there would be a
285 	 * real possibility of deadlock.
286 	 */
287 	args.token = rtas_token("set-indicator");
288 	if (args.token == RTAS_UNKNOWN_SERVICE)
289 		return;
290 	args.nargs = 3;
291 	args.nret = 1;
292 	args.rets = &args.args[3];
293 	args.args[0] = SURVEILLANCE_TOKEN;
294 	args.args[1] = 0;
295 	args.args[2] = 0;
296 	enter_rtas(__pa(&args));
297 #endif /* CONFIG_PPC_PSERIES */
298 }
299 
300 #ifdef CONFIG_SMP
301 static int xmon_speaker;
302 
get_output_lock(void)303 static void get_output_lock(void)
304 {
305 	int me = smp_processor_id() + 0x100;
306 	int last_speaker = 0, prev;
307 	long timeout;
308 
309 	if (xmon_speaker == me)
310 		return;
311 	for (;;) {
312 		if (xmon_speaker == 0) {
313 			last_speaker = cmpxchg(&xmon_speaker, 0, me);
314 			if (last_speaker == 0)
315 				return;
316 		}
317 		timeout = 10000000;
318 		while (xmon_speaker == last_speaker) {
319 			if (--timeout > 0)
320 				continue;
321 			/* hostile takeover */
322 			prev = cmpxchg(&xmon_speaker, last_speaker, me);
323 			if (prev == last_speaker)
324 				return;
325 			break;
326 		}
327 	}
328 }
329 
release_output_lock(void)330 static void release_output_lock(void)
331 {
332 	xmon_speaker = 0;
333 }
334 
cpus_are_in_xmon(void)335 int cpus_are_in_xmon(void)
336 {
337 	return !cpus_empty(cpus_in_xmon);
338 }
339 #endif
340 
unrecoverable_excp(struct pt_regs * regs)341 static inline int unrecoverable_excp(struct pt_regs *regs)
342 {
343 #ifdef CONFIG_4xx
344 	/* We have no MSR_RI bit on 4xx, so we simply return false */
345 	return 0;
346 #else
347 	return ((regs->msr & MSR_RI) == 0);
348 #endif
349 }
350 
xmon_core(struct pt_regs * regs,int fromipi)351 static int xmon_core(struct pt_regs *regs, int fromipi)
352 {
353 	int cmd = 0;
354 	struct bpt *bp;
355 	long recurse_jmp[JMP_BUF_LEN];
356 	unsigned long offset;
357 	unsigned long flags;
358 #ifdef CONFIG_SMP
359 	int cpu;
360 	int secondary;
361 	unsigned long timeout;
362 #endif
363 
364 	local_irq_save(flags);
365 
366 	bp = in_breakpoint_table(regs->nip, &offset);
367 	if (bp != NULL) {
368 		regs->nip = bp->address + offset;
369 		atomic_dec(&bp->ref_count);
370 	}
371 
372 	remove_cpu_bpts();
373 
374 #ifdef CONFIG_SMP
375 	cpu = smp_processor_id();
376 	if (cpu_isset(cpu, cpus_in_xmon)) {
377 		get_output_lock();
378 		excprint(regs);
379 		printf("cpu 0x%x: Exception %lx %s in xmon, "
380 		       "returning to main loop\n",
381 		       cpu, regs->trap, getvecname(TRAP(regs)));
382 		release_output_lock();
383 		longjmp(xmon_fault_jmp[cpu], 1);
384 	}
385 
386 	if (setjmp(recurse_jmp) != 0) {
387 		if (!in_xmon || !xmon_gate) {
388 			get_output_lock();
389 			printf("xmon: WARNING: bad recursive fault "
390 			       "on cpu 0x%x\n", cpu);
391 			release_output_lock();
392 			goto waiting;
393 		}
394 		secondary = !(xmon_taken && cpu == xmon_owner);
395 		goto cmdloop;
396 	}
397 
398 	xmon_fault_jmp[cpu] = recurse_jmp;
399 	cpu_set(cpu, cpus_in_xmon);
400 
401 	bp = NULL;
402 	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
403 		bp = at_breakpoint(regs->nip);
404 	if (bp || unrecoverable_excp(regs))
405 		fromipi = 0;
406 
407 	if (!fromipi) {
408 		get_output_lock();
409 		excprint(regs);
410 		if (bp) {
411 			printf("cpu 0x%x stopped at breakpoint 0x%x (",
412 			       cpu, BP_NUM(bp));
413 			xmon_print_symbol(regs->nip, " ", ")\n");
414 		}
415 		if (unrecoverable_excp(regs))
416 			printf("WARNING: exception is not recoverable, "
417 			       "can't continue\n");
418 		release_output_lock();
419 	}
420 
421  waiting:
422 	secondary = 1;
423 	while (secondary && !xmon_gate) {
424 		if (in_xmon == 0) {
425 			if (fromipi)
426 				goto leave;
427 			secondary = test_and_set_bit(0, &in_xmon);
428 		}
429 		barrier();
430 	}
431 
432 	if (!secondary && !xmon_gate) {
433 		/* we are the first cpu to come in */
434 		/* interrupt other cpu(s) */
435 		int ncpus = num_online_cpus();
436 
437 		xmon_owner = cpu;
438 		mb();
439 		if (ncpus > 1) {
440 			smp_send_debugger_break(MSG_ALL_BUT_SELF);
441 			/* wait for other cpus to come in */
442 			for (timeout = 100000000; timeout != 0; --timeout) {
443 				if (cpus_weight(cpus_in_xmon) >= ncpus)
444 					break;
445 				barrier();
446 			}
447 		}
448 		remove_bpts();
449 		disable_surveillance();
450 		/* for breakpoint or single step, print the current instr. */
451 		if (bp || TRAP(regs) == 0xd00)
452 			ppc_inst_dump(regs->nip, 1, 0);
453 		printf("enter ? for help\n");
454 		mb();
455 		xmon_gate = 1;
456 		barrier();
457 	}
458 
459  cmdloop:
460 	while (in_xmon) {
461 		if (secondary) {
462 			if (cpu == xmon_owner) {
463 				if (!test_and_set_bit(0, &xmon_taken)) {
464 					secondary = 0;
465 					continue;
466 				}
467 				/* missed it */
468 				while (cpu == xmon_owner)
469 					barrier();
470 			}
471 			barrier();
472 		} else {
473 			cmd = cmds(regs);
474 			if (cmd != 0) {
475 				/* exiting xmon */
476 				insert_bpts();
477 				xmon_gate = 0;
478 				wmb();
479 				in_xmon = 0;
480 				break;
481 			}
482 			/* have switched to some other cpu */
483 			secondary = 1;
484 		}
485 	}
486  leave:
487 	cpu_clear(cpu, cpus_in_xmon);
488 	xmon_fault_jmp[cpu] = NULL;
489 #else
490 	/* UP is simple... */
491 	if (in_xmon) {
492 		printf("Exception %lx %s in xmon, returning to main loop\n",
493 		       regs->trap, getvecname(TRAP(regs)));
494 		longjmp(xmon_fault_jmp[0], 1);
495 	}
496 	if (setjmp(recurse_jmp) == 0) {
497 		xmon_fault_jmp[0] = recurse_jmp;
498 		in_xmon = 1;
499 
500 		excprint(regs);
501 		bp = at_breakpoint(regs->nip);
502 		if (bp) {
503 			printf("Stopped at breakpoint %x (", BP_NUM(bp));
504 			xmon_print_symbol(regs->nip, " ", ")\n");
505 		}
506 		if (unrecoverable_excp(regs))
507 			printf("WARNING: exception is not recoverable, "
508 			       "can't continue\n");
509 		remove_bpts();
510 		disable_surveillance();
511 		/* for breakpoint or single step, print the current instr. */
512 		if (bp || TRAP(regs) == 0xd00)
513 			ppc_inst_dump(regs->nip, 1, 0);
514 		printf("enter ? for help\n");
515 	}
516 
517 	cmd = cmds(regs);
518 
519 	insert_bpts();
520 	in_xmon = 0;
521 #endif
522 
523 #ifdef CONFIG_BOOKE
524 	if (regs->msr & MSR_DE) {
525 		bp = at_breakpoint(regs->nip);
526 		if (bp != NULL) {
527 			regs->nip = (unsigned long) &bp->instr[0];
528 			atomic_inc(&bp->ref_count);
529 		}
530 	}
531 #else
532 	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
533 		bp = at_breakpoint(regs->nip);
534 		if (bp != NULL) {
535 			int stepped = emulate_step(regs, bp->instr[0]);
536 			if (stepped == 0) {
537 				regs->nip = (unsigned long) &bp->instr[0];
538 				atomic_inc(&bp->ref_count);
539 			} else if (stepped < 0) {
540 				printf("Couldn't single-step %s instruction\n",
541 				    (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
542 			}
543 		}
544 	}
545 #endif
546 	insert_cpu_bpts();
547 
548 	local_irq_restore(flags);
549 
550 	return cmd != 'X' && cmd != EOF;
551 }
552 
xmon(struct pt_regs * excp)553 int xmon(struct pt_regs *excp)
554 {
555 	struct pt_regs regs;
556 
557 	if (excp == NULL) {
558 		ppc_save_regs(&regs);
559 		excp = &regs;
560 	}
561 
562 	return xmon_core(excp, 0);
563 }
564 EXPORT_SYMBOL(xmon);
565 
xmon_irq(int irq,void * d)566 irqreturn_t xmon_irq(int irq, void *d)
567 {
568 	unsigned long flags;
569 	local_irq_save(flags);
570 	printf("Keyboard interrupt\n");
571 	xmon(get_irq_regs());
572 	local_irq_restore(flags);
573 	return IRQ_HANDLED;
574 }
575 
xmon_bpt(struct pt_regs * regs)576 static int xmon_bpt(struct pt_regs *regs)
577 {
578 	struct bpt *bp;
579 	unsigned long offset;
580 
581 	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
582 		return 0;
583 
584 	/* Are we at the trap at bp->instr[1] for some bp? */
585 	bp = in_breakpoint_table(regs->nip, &offset);
586 	if (bp != NULL && offset == 4) {
587 		regs->nip = bp->address + 4;
588 		atomic_dec(&bp->ref_count);
589 		return 1;
590 	}
591 
592 	/* Are we at a breakpoint? */
593 	bp = at_breakpoint(regs->nip);
594 	if (!bp)
595 		return 0;
596 
597 	xmon_core(regs, 0);
598 
599 	return 1;
600 }
601 
xmon_sstep(struct pt_regs * regs)602 static int xmon_sstep(struct pt_regs *regs)
603 {
604 	if (user_mode(regs))
605 		return 0;
606 	xmon_core(regs, 0);
607 	return 1;
608 }
609 
xmon_dabr_match(struct pt_regs * regs)610 static int xmon_dabr_match(struct pt_regs *regs)
611 {
612 	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
613 		return 0;
614 	if (dabr.enabled == 0)
615 		return 0;
616 	xmon_core(regs, 0);
617 	return 1;
618 }
619 
xmon_iabr_match(struct pt_regs * regs)620 static int xmon_iabr_match(struct pt_regs *regs)
621 {
622 	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
623 		return 0;
624 	if (iabr == NULL)
625 		return 0;
626 	xmon_core(regs, 0);
627 	return 1;
628 }
629 
xmon_ipi(struct pt_regs * regs)630 static int xmon_ipi(struct pt_regs *regs)
631 {
632 #ifdef CONFIG_SMP
633 	if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
634 		xmon_core(regs, 1);
635 #endif
636 	return 0;
637 }
638 
xmon_fault_handler(struct pt_regs * regs)639 static int xmon_fault_handler(struct pt_regs *regs)
640 {
641 	struct bpt *bp;
642 	unsigned long offset;
643 
644 	if (in_xmon && catch_memory_errors)
645 		handle_fault(regs);	/* doesn't return */
646 
647 	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
648 		bp = in_breakpoint_table(regs->nip, &offset);
649 		if (bp != NULL) {
650 			regs->nip = bp->address + offset;
651 			atomic_dec(&bp->ref_count);
652 		}
653 	}
654 
655 	return 0;
656 }
657 
at_breakpoint(unsigned long pc)658 static struct bpt *at_breakpoint(unsigned long pc)
659 {
660 	int i;
661 	struct bpt *bp;
662 
663 	bp = bpts;
664 	for (i = 0; i < NBPTS; ++i, ++bp)
665 		if (bp->enabled && pc == bp->address)
666 			return bp;
667 	return NULL;
668 }
669 
in_breakpoint_table(unsigned long nip,unsigned long * offp)670 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
671 {
672 	unsigned long off;
673 
674 	off = nip - (unsigned long) bpts;
675 	if (off >= sizeof(bpts))
676 		return NULL;
677 	off %= sizeof(struct bpt);
678 	if (off != offsetof(struct bpt, instr[0])
679 	    && off != offsetof(struct bpt, instr[1]))
680 		return NULL;
681 	*offp = off - offsetof(struct bpt, instr[0]);
682 	return (struct bpt *) (nip - off);
683 }
684 
new_breakpoint(unsigned long a)685 static struct bpt *new_breakpoint(unsigned long a)
686 {
687 	struct bpt *bp;
688 
689 	a &= ~3UL;
690 	bp = at_breakpoint(a);
691 	if (bp)
692 		return bp;
693 
694 	for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
695 		if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
696 			bp->address = a;
697 			bp->instr[1] = bpinstr;
698 			store_inst(&bp->instr[1]);
699 			return bp;
700 		}
701 	}
702 
703 	printf("Sorry, no free breakpoints.  Please clear one first.\n");
704 	return NULL;
705 }
706 
insert_bpts(void)707 static void insert_bpts(void)
708 {
709 	int i;
710 	struct bpt *bp;
711 
712 	bp = bpts;
713 	for (i = 0; i < NBPTS; ++i, ++bp) {
714 		if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
715 			continue;
716 		if (mread(bp->address, &bp->instr[0], 4) != 4) {
717 			printf("Couldn't read instruction at %lx, "
718 			       "disabling breakpoint there\n", bp->address);
719 			bp->enabled = 0;
720 			continue;
721 		}
722 		if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
723 			printf("Breakpoint at %lx is on an mtmsrd or rfid "
724 			       "instruction, disabling it\n", bp->address);
725 			bp->enabled = 0;
726 			continue;
727 		}
728 		store_inst(&bp->instr[0]);
729 		if (bp->enabled & BP_IABR)
730 			continue;
731 		if (mwrite(bp->address, &bpinstr, 4) != 4) {
732 			printf("Couldn't write instruction at %lx, "
733 			       "disabling breakpoint there\n", bp->address);
734 			bp->enabled &= ~BP_TRAP;
735 			continue;
736 		}
737 		store_inst((void *)bp->address);
738 	}
739 }
740 
insert_cpu_bpts(void)741 static void insert_cpu_bpts(void)
742 {
743 	if (dabr.enabled)
744 		set_dabr(dabr.address | (dabr.enabled & 7));
745 	if (iabr && cpu_has_feature(CPU_FTR_IABR))
746 		mtspr(SPRN_IABR, iabr->address
747 			 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
748 }
749 
remove_bpts(void)750 static void remove_bpts(void)
751 {
752 	int i;
753 	struct bpt *bp;
754 	unsigned instr;
755 
756 	bp = bpts;
757 	for (i = 0; i < NBPTS; ++i, ++bp) {
758 		if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
759 			continue;
760 		if (mread(bp->address, &instr, 4) == 4
761 		    && instr == bpinstr
762 		    && mwrite(bp->address, &bp->instr, 4) != 4)
763 			printf("Couldn't remove breakpoint at %lx\n",
764 			       bp->address);
765 		else
766 			store_inst((void *)bp->address);
767 	}
768 }
769 
remove_cpu_bpts(void)770 static void remove_cpu_bpts(void)
771 {
772 	set_dabr(0);
773 	if (cpu_has_feature(CPU_FTR_IABR))
774 		mtspr(SPRN_IABR, 0);
775 }
776 
777 /* Command interpreting routine */
778 static char *last_cmd;
779 
780 static int
cmds(struct pt_regs * excp)781 cmds(struct pt_regs *excp)
782 {
783 	int cmd = 0;
784 
785 	last_cmd = NULL;
786 	xmon_regs = excp;
787 
788 	if (!xmon_no_auto_backtrace) {
789 		xmon_no_auto_backtrace = 1;
790 		xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
791 	}
792 
793 	for(;;) {
794 #ifdef CONFIG_SMP
795 		printf("%x:", smp_processor_id());
796 #endif /* CONFIG_SMP */
797 		printf("mon> ");
798 		flush_input();
799 		termch = 0;
800 		cmd = skipbl();
801 		if( cmd == '\n' ) {
802 			if (last_cmd == NULL)
803 				continue;
804 			take_input(last_cmd);
805 			last_cmd = NULL;
806 			cmd = inchar();
807 		}
808 		switch (cmd) {
809 		case 'm':
810 			cmd = inchar();
811 			switch (cmd) {
812 			case 'm':
813 			case 's':
814 			case 'd':
815 				memops(cmd);
816 				break;
817 			case 'l':
818 				memlocate();
819 				break;
820 			case 'z':
821 				memzcan();
822 				break;
823 			case 'i':
824 				show_mem(0);
825 				break;
826 			default:
827 				termch = cmd;
828 				memex();
829 			}
830 			break;
831 		case 'd':
832 			dump();
833 			break;
834 		case 'l':
835 			symbol_lookup();
836 			break;
837 		case 'r':
838 			prregs(excp);	/* print regs */
839 			break;
840 		case 'e':
841 			excprint(excp);
842 			break;
843 		case 'S':
844 			super_regs();
845 			break;
846 		case 't':
847 			backtrace(excp);
848 			break;
849 		case 'f':
850 			cacheflush();
851 			break;
852 		case 's':
853 			if (do_spu_cmd() == 0)
854 				break;
855 			if (do_step(excp))
856 				return cmd;
857 			break;
858 		case 'x':
859 		case 'X':
860 			return cmd;
861 		case EOF:
862 			printf(" <no input ...>\n");
863 			mdelay(2000);
864 			return cmd;
865 		case '?':
866 			xmon_puts(help_string);
867 			break;
868 		case 'b':
869 			bpt_cmds();
870 			break;
871 		case 'C':
872 			csum();
873 			break;
874 		case 'c':
875 			if (cpu_cmd())
876 				return 0;
877 			break;
878 		case 'z':
879 			bootcmds();
880 			break;
881 		case 'p':
882 			proccall();
883 			break;
884 #ifdef CONFIG_PPC_STD_MMU
885 		case 'u':
886 			dump_segments();
887 			break;
888 #endif
889 #ifdef CONFIG_4xx
890 		case 'u':
891 			dump_tlb_44x();
892 			break;
893 #endif
894 #ifdef CONFIG_PPC_BOOK3E
895 		case 'u':
896 			dump_tlb_book3e();
897 			break;
898 #endif
899 		default:
900 			printf("Unrecognized command: ");
901 		        do {
902 				if (' ' < cmd && cmd <= '~')
903 					putchar(cmd);
904 				else
905 					printf("\\x%x", cmd);
906 				cmd = inchar();
907 		        } while (cmd != '\n');
908 			printf(" (type ? for help)\n");
909 			break;
910 		}
911 	}
912 }
913 
914 #ifdef CONFIG_BOOKE
do_step(struct pt_regs * regs)915 static int do_step(struct pt_regs *regs)
916 {
917 	regs->msr |= MSR_DE;
918 	mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
919 	return 1;
920 }
921 #else
922 /*
923  * Step a single instruction.
924  * Some instructions we emulate, others we execute with MSR_SE set.
925  */
do_step(struct pt_regs * regs)926 static int do_step(struct pt_regs *regs)
927 {
928 	unsigned int instr;
929 	int stepped;
930 
931 	/* check we are in 64-bit kernel mode, translation enabled */
932 	if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
933 		if (mread(regs->nip, &instr, 4) == 4) {
934 			stepped = emulate_step(regs, instr);
935 			if (stepped < 0) {
936 				printf("Couldn't single-step %s instruction\n",
937 				       (IS_RFID(instr)? "rfid": "mtmsrd"));
938 				return 0;
939 			}
940 			if (stepped > 0) {
941 				regs->trap = 0xd00 | (regs->trap & 1);
942 				printf("stepped to ");
943 				xmon_print_symbol(regs->nip, " ", "\n");
944 				ppc_inst_dump(regs->nip, 1, 0);
945 				return 0;
946 			}
947 		}
948 	}
949 	regs->msr |= MSR_SE;
950 	return 1;
951 }
952 #endif
953 
bootcmds(void)954 static void bootcmds(void)
955 {
956 	int cmd;
957 
958 	cmd = inchar();
959 	if (cmd == 'r')
960 		ppc_md.restart(NULL);
961 	else if (cmd == 'h')
962 		ppc_md.halt();
963 	else if (cmd == 'p')
964 		ppc_md.power_off();
965 }
966 
cpu_cmd(void)967 static int cpu_cmd(void)
968 {
969 #ifdef CONFIG_SMP
970 	unsigned long cpu;
971 	int timeout;
972 	int count;
973 
974 	if (!scanhex(&cpu)) {
975 		/* print cpus waiting or in xmon */
976 		printf("cpus stopped:");
977 		count = 0;
978 		for (cpu = 0; cpu < NR_CPUS; ++cpu) {
979 			if (cpu_isset(cpu, cpus_in_xmon)) {
980 				if (count == 0)
981 					printf(" %x", cpu);
982 				++count;
983 			} else {
984 				if (count > 1)
985 					printf("-%x", cpu - 1);
986 				count = 0;
987 			}
988 		}
989 		if (count > 1)
990 			printf("-%x", NR_CPUS - 1);
991 		printf("\n");
992 		return 0;
993 	}
994 	/* try to switch to cpu specified */
995 	if (!cpu_isset(cpu, cpus_in_xmon)) {
996 		printf("cpu 0x%x isn't in xmon\n", cpu);
997 		return 0;
998 	}
999 	xmon_taken = 0;
1000 	mb();
1001 	xmon_owner = cpu;
1002 	timeout = 10000000;
1003 	while (!xmon_taken) {
1004 		if (--timeout == 0) {
1005 			if (test_and_set_bit(0, &xmon_taken))
1006 				break;
1007 			/* take control back */
1008 			mb();
1009 			xmon_owner = smp_processor_id();
1010 			printf("cpu %u didn't take control\n", cpu);
1011 			return 0;
1012 		}
1013 		barrier();
1014 	}
1015 	return 1;
1016 #else
1017 	return 0;
1018 #endif /* CONFIG_SMP */
1019 }
1020 
1021 static unsigned short fcstab[256] = {
1022 	0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
1023 	0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
1024 	0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
1025 	0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1026 	0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1027 	0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1028 	0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1029 	0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1030 	0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1031 	0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1032 	0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1033 	0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1034 	0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1035 	0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1036 	0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1037 	0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1038 	0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1039 	0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1040 	0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1041 	0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1042 	0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1043 	0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1044 	0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1045 	0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1046 	0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1047 	0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1048 	0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1049 	0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1050 	0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1051 	0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1052 	0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1053 	0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1054 };
1055 
1056 #define FCS(fcs, c)	(((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1057 
1058 static void
csum(void)1059 csum(void)
1060 {
1061 	unsigned int i;
1062 	unsigned short fcs;
1063 	unsigned char v;
1064 
1065 	if (!scanhex(&adrs))
1066 		return;
1067 	if (!scanhex(&ncsum))
1068 		return;
1069 	fcs = 0xffff;
1070 	for (i = 0; i < ncsum; ++i) {
1071 		if (mread(adrs+i, &v, 1) == 0) {
1072 			printf("csum stopped at %x\n", adrs+i);
1073 			break;
1074 		}
1075 		fcs = FCS(fcs, v);
1076 	}
1077 	printf("%x\n", fcs);
1078 }
1079 
1080 /*
1081  * Check if this is a suitable place to put a breakpoint.
1082  */
check_bp_loc(unsigned long addr)1083 static long check_bp_loc(unsigned long addr)
1084 {
1085 	unsigned int instr;
1086 
1087 	addr &= ~3;
1088 	if (!is_kernel_addr(addr)) {
1089 		printf("Breakpoints may only be placed at kernel addresses\n");
1090 		return 0;
1091 	}
1092 	if (!mread(addr, &instr, sizeof(instr))) {
1093 		printf("Can't read instruction at address %lx\n", addr);
1094 		return 0;
1095 	}
1096 	if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1097 		printf("Breakpoints may not be placed on mtmsrd or rfid "
1098 		       "instructions\n");
1099 		return 0;
1100 	}
1101 	return 1;
1102 }
1103 
1104 static char *breakpoint_help_string =
1105     "Breakpoint command usage:\n"
1106     "b                show breakpoints\n"
1107     "b <addr> [cnt]   set breakpoint at given instr addr\n"
1108     "bc               clear all breakpoints\n"
1109     "bc <n/addr>      clear breakpoint number n or at addr\n"
1110     "bi <addr> [cnt]  set hardware instr breakpoint (POWER3/RS64 only)\n"
1111     "bd <addr> [cnt]  set hardware data breakpoint\n"
1112     "";
1113 
1114 static void
bpt_cmds(void)1115 bpt_cmds(void)
1116 {
1117 	int cmd;
1118 	unsigned long a;
1119 	int mode, i;
1120 	struct bpt *bp;
1121 	const char badaddr[] = "Only kernel addresses are permitted "
1122 		"for breakpoints\n";
1123 
1124 	cmd = inchar();
1125 	switch (cmd) {
1126 #ifndef CONFIG_8xx
1127 	case 'd':	/* bd - hardware data breakpoint */
1128 		mode = 7;
1129 		cmd = inchar();
1130 		if (cmd == 'r')
1131 			mode = 5;
1132 		else if (cmd == 'w')
1133 			mode = 6;
1134 		else
1135 			termch = cmd;
1136 		dabr.address = 0;
1137 		dabr.enabled = 0;
1138 		if (scanhex(&dabr.address)) {
1139 			if (!is_kernel_addr(dabr.address)) {
1140 				printf(badaddr);
1141 				break;
1142 			}
1143 			dabr.address &= ~7;
1144 			dabr.enabled = mode | BP_DABR;
1145 		}
1146 		break;
1147 
1148 	case 'i':	/* bi - hardware instr breakpoint */
1149 		if (!cpu_has_feature(CPU_FTR_IABR)) {
1150 			printf("Hardware instruction breakpoint "
1151 			       "not supported on this cpu\n");
1152 			break;
1153 		}
1154 		if (iabr) {
1155 			iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1156 			iabr = NULL;
1157 		}
1158 		if (!scanhex(&a))
1159 			break;
1160 		if (!check_bp_loc(a))
1161 			break;
1162 		bp = new_breakpoint(a);
1163 		if (bp != NULL) {
1164 			bp->enabled |= BP_IABR | BP_IABR_TE;
1165 			iabr = bp;
1166 		}
1167 		break;
1168 #endif
1169 
1170 	case 'c':
1171 		if (!scanhex(&a)) {
1172 			/* clear all breakpoints */
1173 			for (i = 0; i < NBPTS; ++i)
1174 				bpts[i].enabled = 0;
1175 			iabr = NULL;
1176 			dabr.enabled = 0;
1177 			printf("All breakpoints cleared\n");
1178 			break;
1179 		}
1180 
1181 		if (a <= NBPTS && a >= 1) {
1182 			/* assume a breakpoint number */
1183 			bp = &bpts[a-1];	/* bp nums are 1 based */
1184 		} else {
1185 			/* assume a breakpoint address */
1186 			bp = at_breakpoint(a);
1187 			if (bp == NULL) {
1188 				printf("No breakpoint at %x\n", a);
1189 				break;
1190 			}
1191 		}
1192 
1193 		printf("Cleared breakpoint %x (", BP_NUM(bp));
1194 		xmon_print_symbol(bp->address, " ", ")\n");
1195 		bp->enabled = 0;
1196 		break;
1197 
1198 	default:
1199 		termch = cmd;
1200 	        cmd = skipbl();
1201 		if (cmd == '?') {
1202 			printf(breakpoint_help_string);
1203 			break;
1204 		}
1205 		termch = cmd;
1206 		if (!scanhex(&a)) {
1207 			/* print all breakpoints */
1208 			printf("   type            address\n");
1209 			if (dabr.enabled) {
1210 				printf("   data   "REG"  [", dabr.address);
1211 				if (dabr.enabled & 1)
1212 					printf("r");
1213 				if (dabr.enabled & 2)
1214 					printf("w");
1215 				printf("]\n");
1216 			}
1217 			for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1218 				if (!bp->enabled)
1219 					continue;
1220 				printf("%2x %s   ", BP_NUM(bp),
1221 				    (bp->enabled & BP_IABR)? "inst": "trap");
1222 				xmon_print_symbol(bp->address, "  ", "\n");
1223 			}
1224 			break;
1225 		}
1226 
1227 		if (!check_bp_loc(a))
1228 			break;
1229 		bp = new_breakpoint(a);
1230 		if (bp != NULL)
1231 			bp->enabled |= BP_TRAP;
1232 		break;
1233 	}
1234 }
1235 
1236 /* Very cheap human name for vector lookup. */
1237 static
getvecname(unsigned long vec)1238 const char *getvecname(unsigned long vec)
1239 {
1240 	char *ret;
1241 
1242 	switch (vec) {
1243 	case 0x100:	ret = "(System Reset)"; break;
1244 	case 0x200:	ret = "(Machine Check)"; break;
1245 	case 0x300:	ret = "(Data Access)"; break;
1246 	case 0x380:	ret = "(Data SLB Access)"; break;
1247 	case 0x400:	ret = "(Instruction Access)"; break;
1248 	case 0x480:	ret = "(Instruction SLB Access)"; break;
1249 	case 0x500:	ret = "(Hardware Interrupt)"; break;
1250 	case 0x600:	ret = "(Alignment)"; break;
1251 	case 0x700:	ret = "(Program Check)"; break;
1252 	case 0x800:	ret = "(FPU Unavailable)"; break;
1253 	case 0x900:	ret = "(Decrementer)"; break;
1254 	case 0xc00:	ret = "(System Call)"; break;
1255 	case 0xd00:	ret = "(Single Step)"; break;
1256 	case 0xf00:	ret = "(Performance Monitor)"; break;
1257 	case 0xf20:	ret = "(Altivec Unavailable)"; break;
1258 	case 0x1300:	ret = "(Instruction Breakpoint)"; break;
1259 	default: ret = "";
1260 	}
1261 	return ret;
1262 }
1263 
get_function_bounds(unsigned long pc,unsigned long * startp,unsigned long * endp)1264 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1265 				unsigned long *endp)
1266 {
1267 	unsigned long size, offset;
1268 	const char *name;
1269 
1270 	*startp = *endp = 0;
1271 	if (pc == 0)
1272 		return;
1273 	if (setjmp(bus_error_jmp) == 0) {
1274 		catch_memory_errors = 1;
1275 		sync();
1276 		name = kallsyms_lookup(pc, &size, &offset, NULL, tmpstr);
1277 		if (name != NULL) {
1278 			*startp = pc - offset;
1279 			*endp = pc - offset + size;
1280 		}
1281 		sync();
1282 	}
1283 	catch_memory_errors = 0;
1284 }
1285 
1286 static int xmon_depth_to_print = 64;
1287 
1288 #define LRSAVE_OFFSET		(STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1289 #define MARKER_OFFSET		(STACK_FRAME_MARKER * sizeof(unsigned long))
1290 
1291 #ifdef __powerpc64__
1292 #define REGS_OFFSET		0x70
1293 #else
1294 #define REGS_OFFSET		16
1295 #endif
1296 
xmon_show_stack(unsigned long sp,unsigned long lr,unsigned long pc)1297 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1298 			    unsigned long pc)
1299 {
1300 	unsigned long ip;
1301 	unsigned long newsp;
1302 	unsigned long marker;
1303 	int count = 0;
1304 	struct pt_regs regs;
1305 
1306 	do {
1307 		if (sp < PAGE_OFFSET) {
1308 			if (sp != 0)
1309 				printf("SP (%lx) is in userspace\n", sp);
1310 			break;
1311 		}
1312 
1313 		if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1314 		    || !mread(sp, &newsp, sizeof(unsigned long))) {
1315 			printf("Couldn't read stack frame at %lx\n", sp);
1316 			break;
1317 		}
1318 
1319 		/*
1320 		 * For the first stack frame, try to work out if
1321 		 * LR and/or the saved LR value in the bottommost
1322 		 * stack frame are valid.
1323 		 */
1324 		if ((pc | lr) != 0) {
1325 			unsigned long fnstart, fnend;
1326 			unsigned long nextip;
1327 			int printip = 1;
1328 
1329 			get_function_bounds(pc, &fnstart, &fnend);
1330 			nextip = 0;
1331 			if (newsp > sp)
1332 				mread(newsp + LRSAVE_OFFSET, &nextip,
1333 				      sizeof(unsigned long));
1334 			if (lr == ip) {
1335 				if (lr < PAGE_OFFSET
1336 				    || (fnstart <= lr && lr < fnend))
1337 					printip = 0;
1338 			} else if (lr == nextip) {
1339 				printip = 0;
1340 			} else if (lr >= PAGE_OFFSET
1341 				   && !(fnstart <= lr && lr < fnend)) {
1342 				printf("[link register   ] ");
1343 				xmon_print_symbol(lr, " ", "\n");
1344 			}
1345 			if (printip) {
1346 				printf("["REG"] ", sp);
1347 				xmon_print_symbol(ip, " ", " (unreliable)\n");
1348 			}
1349 			pc = lr = 0;
1350 
1351 		} else {
1352 			printf("["REG"] ", sp);
1353 			xmon_print_symbol(ip, " ", "\n");
1354 		}
1355 
1356 		/* Look for "regshere" marker to see if this is
1357 		   an exception frame. */
1358 		if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1359 		    && marker == STACK_FRAME_REGS_MARKER) {
1360 			if (mread(sp + REGS_OFFSET, &regs, sizeof(regs))
1361 			    != sizeof(regs)) {
1362 				printf("Couldn't read registers at %lx\n",
1363 				       sp + REGS_OFFSET);
1364 				break;
1365 			}
1366                         printf("--- Exception: %lx %s at ", regs.trap,
1367 			       getvecname(TRAP(&regs)));
1368 			pc = regs.nip;
1369 			lr = regs.link;
1370 			xmon_print_symbol(pc, " ", "\n");
1371 		}
1372 
1373 		if (newsp == 0)
1374 			break;
1375 
1376 		sp = newsp;
1377 	} while (count++ < xmon_depth_to_print);
1378 }
1379 
backtrace(struct pt_regs * excp)1380 static void backtrace(struct pt_regs *excp)
1381 {
1382 	unsigned long sp;
1383 
1384 	if (scanhex(&sp))
1385 		xmon_show_stack(sp, 0, 0);
1386 	else
1387 		xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1388 	scannl();
1389 }
1390 
print_bug_trap(struct pt_regs * regs)1391 static void print_bug_trap(struct pt_regs *regs)
1392 {
1393 #ifdef CONFIG_BUG
1394 	const struct bug_entry *bug;
1395 	unsigned long addr;
1396 
1397 	if (regs->msr & MSR_PR)
1398 		return;		/* not in kernel */
1399 	addr = regs->nip;	/* address of trap instruction */
1400 	if (addr < PAGE_OFFSET)
1401 		return;
1402 	bug = find_bug(regs->nip);
1403 	if (bug == NULL)
1404 		return;
1405 	if (is_warning_bug(bug))
1406 		return;
1407 
1408 #ifdef CONFIG_DEBUG_BUGVERBOSE
1409 	printf("kernel BUG at %s:%u!\n",
1410 	       bug->file, bug->line);
1411 #else
1412 	printf("kernel BUG at %p!\n", (void *)bug->bug_addr);
1413 #endif
1414 #endif /* CONFIG_BUG */
1415 }
1416 
excprint(struct pt_regs * fp)1417 static void excprint(struct pt_regs *fp)
1418 {
1419 	unsigned long trap;
1420 
1421 #ifdef CONFIG_SMP
1422 	printf("cpu 0x%x: ", smp_processor_id());
1423 #endif /* CONFIG_SMP */
1424 
1425 	trap = TRAP(fp);
1426 	printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1427 	printf("    pc: ");
1428 	xmon_print_symbol(fp->nip, ": ", "\n");
1429 
1430 	printf("    lr: ", fp->link);
1431 	xmon_print_symbol(fp->link, ": ", "\n");
1432 
1433 	printf("    sp: %lx\n", fp->gpr[1]);
1434 	printf("   msr: %lx\n", fp->msr);
1435 
1436 	if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1437 		printf("   dar: %lx\n", fp->dar);
1438 		if (trap != 0x380)
1439 			printf(" dsisr: %lx\n", fp->dsisr);
1440 	}
1441 
1442 	printf("  current = 0x%lx\n", current);
1443 #ifdef CONFIG_PPC64
1444 	printf("  paca    = 0x%lx\n", get_paca());
1445 #endif
1446 	if (current) {
1447 		printf("    pid   = %ld, comm = %s\n",
1448 		       current->pid, current->comm);
1449 	}
1450 
1451 	if (trap == 0x700)
1452 		print_bug_trap(fp);
1453 }
1454 
prregs(struct pt_regs * fp)1455 static void prregs(struct pt_regs *fp)
1456 {
1457 	int n, trap;
1458 	unsigned long base;
1459 	struct pt_regs regs;
1460 
1461 	if (scanhex(&base)) {
1462 		if (setjmp(bus_error_jmp) == 0) {
1463 			catch_memory_errors = 1;
1464 			sync();
1465 			regs = *(struct pt_regs *)base;
1466 			sync();
1467 			__delay(200);
1468 		} else {
1469 			catch_memory_errors = 0;
1470 			printf("*** Error reading registers from "REG"\n",
1471 			       base);
1472 			return;
1473 		}
1474 		catch_memory_errors = 0;
1475 		fp = &regs;
1476 	}
1477 
1478 #ifdef CONFIG_PPC64
1479 	if (FULL_REGS(fp)) {
1480 		for (n = 0; n < 16; ++n)
1481 			printf("R%.2ld = "REG"   R%.2ld = "REG"\n",
1482 			       n, fp->gpr[n], n+16, fp->gpr[n+16]);
1483 	} else {
1484 		for (n = 0; n < 7; ++n)
1485 			printf("R%.2ld = "REG"   R%.2ld = "REG"\n",
1486 			       n, fp->gpr[n], n+7, fp->gpr[n+7]);
1487 	}
1488 #else
1489 	for (n = 0; n < 32; ++n) {
1490 		printf("R%.2d = %.8x%s", n, fp->gpr[n],
1491 		       (n & 3) == 3? "\n": "   ");
1492 		if (n == 12 && !FULL_REGS(fp)) {
1493 			printf("\n");
1494 			break;
1495 		}
1496 	}
1497 #endif
1498 	printf("pc  = ");
1499 	xmon_print_symbol(fp->nip, " ", "\n");
1500 	printf("lr  = ");
1501 	xmon_print_symbol(fp->link, " ", "\n");
1502 	printf("msr = "REG"   cr  = %.8lx\n", fp->msr, fp->ccr);
1503 	printf("ctr = "REG"   xer = "REG"   trap = %4lx\n",
1504 	       fp->ctr, fp->xer, fp->trap);
1505 	trap = TRAP(fp);
1506 	if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1507 		printf("dar = "REG"   dsisr = %.8lx\n", fp->dar, fp->dsisr);
1508 }
1509 
cacheflush(void)1510 static void cacheflush(void)
1511 {
1512 	int cmd;
1513 	unsigned long nflush;
1514 
1515 	cmd = inchar();
1516 	if (cmd != 'i')
1517 		termch = cmd;
1518 	scanhex((void *)&adrs);
1519 	if (termch != '\n')
1520 		termch = 0;
1521 	nflush = 1;
1522 	scanhex(&nflush);
1523 	nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1524 	if (setjmp(bus_error_jmp) == 0) {
1525 		catch_memory_errors = 1;
1526 		sync();
1527 
1528 		if (cmd != 'i') {
1529 			for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1530 				cflush((void *) adrs);
1531 		} else {
1532 			for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1533 				cinval((void *) adrs);
1534 		}
1535 		sync();
1536 		/* wait a little while to see if we get a machine check */
1537 		__delay(200);
1538 	}
1539 	catch_memory_errors = 0;
1540 }
1541 
1542 static unsigned long
read_spr(int n)1543 read_spr(int n)
1544 {
1545 	unsigned int instrs[2];
1546 	unsigned long (*code)(void);
1547 	unsigned long ret = -1UL;
1548 #ifdef CONFIG_PPC64
1549 	unsigned long opd[3];
1550 
1551 	opd[0] = (unsigned long)instrs;
1552 	opd[1] = 0;
1553 	opd[2] = 0;
1554 	code = (unsigned long (*)(void)) opd;
1555 #else
1556 	code = (unsigned long (*)(void)) instrs;
1557 #endif
1558 
1559 	/* mfspr r3,n; blr */
1560 	instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1561 	instrs[1] = 0x4e800020;
1562 	store_inst(instrs);
1563 	store_inst(instrs+1);
1564 
1565 	if (setjmp(bus_error_jmp) == 0) {
1566 		catch_memory_errors = 1;
1567 		sync();
1568 
1569 		ret = code();
1570 
1571 		sync();
1572 		/* wait a little while to see if we get a machine check */
1573 		__delay(200);
1574 		n = size;
1575 	}
1576 
1577 	return ret;
1578 }
1579 
1580 static void
write_spr(int n,unsigned long val)1581 write_spr(int n, unsigned long val)
1582 {
1583 	unsigned int instrs[2];
1584 	unsigned long (*code)(unsigned long);
1585 #ifdef CONFIG_PPC64
1586 	unsigned long opd[3];
1587 
1588 	opd[0] = (unsigned long)instrs;
1589 	opd[1] = 0;
1590 	opd[2] = 0;
1591 	code = (unsigned long (*)(unsigned long)) opd;
1592 #else
1593 	code = (unsigned long (*)(unsigned long)) instrs;
1594 #endif
1595 
1596 	instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1597 	instrs[1] = 0x4e800020;
1598 	store_inst(instrs);
1599 	store_inst(instrs+1);
1600 
1601 	if (setjmp(bus_error_jmp) == 0) {
1602 		catch_memory_errors = 1;
1603 		sync();
1604 
1605 		code(val);
1606 
1607 		sync();
1608 		/* wait a little while to see if we get a machine check */
1609 		__delay(200);
1610 		n = size;
1611 	}
1612 }
1613 
1614 static unsigned long regno;
1615 extern char exc_prolog;
1616 extern char dec_exc;
1617 
super_regs(void)1618 static void super_regs(void)
1619 {
1620 	int cmd;
1621 	unsigned long val;
1622 
1623 	cmd = skipbl();
1624 	if (cmd == '\n') {
1625 	        unsigned long sp, toc;
1626 		asm("mr %0,1" : "=r" (sp) :);
1627 		asm("mr %0,2" : "=r" (toc) :);
1628 
1629 		printf("msr  = "REG"  sprg0= "REG"\n",
1630 		       mfmsr(), mfspr(SPRN_SPRG0));
1631 		printf("pvr  = "REG"  sprg1= "REG"\n",
1632 		       mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
1633 		printf("dec  = "REG"  sprg2= "REG"\n",
1634 		       mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1635 		printf("sp   = "REG"  sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1636 		printf("toc  = "REG"  dar  = "REG"\n", toc, mfspr(SPRN_DAR));
1637 #ifdef CONFIG_PPC_ISERIES
1638 		if (firmware_has_feature(FW_FEATURE_ISERIES)) {
1639 			struct paca_struct *ptrPaca;
1640 			struct lppaca *ptrLpPaca;
1641 
1642 			/* Dump out relevant Paca data areas. */
1643 			printf("Paca: \n");
1644 			ptrPaca = get_paca();
1645 
1646 			printf("  Local Processor Control Area (LpPaca): \n");
1647 			ptrLpPaca = ptrPaca->lppaca_ptr;
1648 			printf("    Saved Srr0=%.16lx  Saved Srr1=%.16lx \n",
1649 			       ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
1650 			printf("    Saved Gpr3=%.16lx  Saved Gpr4=%.16lx \n",
1651 			       ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
1652 			printf("    Saved Gpr5=%.16lx \n",
1653 				ptrLpPaca->gpr5_dword.saved_gpr5);
1654 		}
1655 #endif
1656 
1657 		return;
1658 	}
1659 
1660 	scanhex(&regno);
1661 	switch (cmd) {
1662 	case 'w':
1663 		val = read_spr(regno);
1664 		scanhex(&val);
1665 		write_spr(regno, val);
1666 		/* fall through */
1667 	case 'r':
1668 		printf("spr %lx = %lx\n", regno, read_spr(regno));
1669 		break;
1670 	}
1671 	scannl();
1672 }
1673 
1674 /*
1675  * Stuff for reading and writing memory safely
1676  */
1677 static int
mread(unsigned long adrs,void * buf,int size)1678 mread(unsigned long adrs, void *buf, int size)
1679 {
1680 	volatile int n;
1681 	char *p, *q;
1682 
1683 	n = 0;
1684 	if (setjmp(bus_error_jmp) == 0) {
1685 		catch_memory_errors = 1;
1686 		sync();
1687 		p = (char *)adrs;
1688 		q = (char *)buf;
1689 		switch (size) {
1690 		case 2:
1691 			*(u16 *)q = *(u16 *)p;
1692 			break;
1693 		case 4:
1694 			*(u32 *)q = *(u32 *)p;
1695 			break;
1696 		case 8:
1697 			*(u64 *)q = *(u64 *)p;
1698 			break;
1699 		default:
1700 			for( ; n < size; ++n) {
1701 				*q++ = *p++;
1702 				sync();
1703 			}
1704 		}
1705 		sync();
1706 		/* wait a little while to see if we get a machine check */
1707 		__delay(200);
1708 		n = size;
1709 	}
1710 	catch_memory_errors = 0;
1711 	return n;
1712 }
1713 
1714 static int
mwrite(unsigned long adrs,void * buf,int size)1715 mwrite(unsigned long adrs, void *buf, int size)
1716 {
1717 	volatile int n;
1718 	char *p, *q;
1719 
1720 	n = 0;
1721 	if (setjmp(bus_error_jmp) == 0) {
1722 		catch_memory_errors = 1;
1723 		sync();
1724 		p = (char *) adrs;
1725 		q = (char *) buf;
1726 		switch (size) {
1727 		case 2:
1728 			*(u16 *)p = *(u16 *)q;
1729 			break;
1730 		case 4:
1731 			*(u32 *)p = *(u32 *)q;
1732 			break;
1733 		case 8:
1734 			*(u64 *)p = *(u64 *)q;
1735 			break;
1736 		default:
1737 			for ( ; n < size; ++n) {
1738 				*p++ = *q++;
1739 				sync();
1740 			}
1741 		}
1742 		sync();
1743 		/* wait a little while to see if we get a machine check */
1744 		__delay(200);
1745 		n = size;
1746 	} else {
1747 		printf("*** Error writing address %x\n", adrs + n);
1748 	}
1749 	catch_memory_errors = 0;
1750 	return n;
1751 }
1752 
1753 static int fault_type;
1754 static int fault_except;
1755 static char *fault_chars[] = { "--", "**", "##" };
1756 
handle_fault(struct pt_regs * regs)1757 static int handle_fault(struct pt_regs *regs)
1758 {
1759 	fault_except = TRAP(regs);
1760 	switch (TRAP(regs)) {
1761 	case 0x200:
1762 		fault_type = 0;
1763 		break;
1764 	case 0x300:
1765 	case 0x380:
1766 		fault_type = 1;
1767 		break;
1768 	default:
1769 		fault_type = 2;
1770 	}
1771 
1772 	longjmp(bus_error_jmp, 1);
1773 
1774 	return 0;
1775 }
1776 
1777 #define SWAP(a, b, t)	((t) = (a), (a) = (b), (b) = (t))
1778 
1779 static void
byterev(unsigned char * val,int size)1780 byterev(unsigned char *val, int size)
1781 {
1782 	int t;
1783 
1784 	switch (size) {
1785 	case 2:
1786 		SWAP(val[0], val[1], t);
1787 		break;
1788 	case 4:
1789 		SWAP(val[0], val[3], t);
1790 		SWAP(val[1], val[2], t);
1791 		break;
1792 	case 8: /* is there really any use for this? */
1793 		SWAP(val[0], val[7], t);
1794 		SWAP(val[1], val[6], t);
1795 		SWAP(val[2], val[5], t);
1796 		SWAP(val[3], val[4], t);
1797 		break;
1798 	}
1799 }
1800 
1801 static int brev;
1802 static int mnoread;
1803 
1804 static char *memex_help_string =
1805     "Memory examine command usage:\n"
1806     "m [addr] [flags] examine/change memory\n"
1807     "  addr is optional.  will start where left off.\n"
1808     "  flags may include chars from this set:\n"
1809     "    b   modify by bytes (default)\n"
1810     "    w   modify by words (2 byte)\n"
1811     "    l   modify by longs (4 byte)\n"
1812     "    d   modify by doubleword (8 byte)\n"
1813     "    r   toggle reverse byte order mode\n"
1814     "    n   do not read memory (for i/o spaces)\n"
1815     "    .   ok to read (default)\n"
1816     "NOTE: flags are saved as defaults\n"
1817     "";
1818 
1819 static char *memex_subcmd_help_string =
1820     "Memory examine subcommands:\n"
1821     "  hexval   write this val to current location\n"
1822     "  'string' write chars from string to this location\n"
1823     "  '        increment address\n"
1824     "  ^        decrement address\n"
1825     "  /        increment addr by 0x10.  //=0x100, ///=0x1000, etc\n"
1826     "  \\        decrement addr by 0x10.  \\\\=0x100, \\\\\\=0x1000, etc\n"
1827     "  `        clear no-read flag\n"
1828     "  ;        stay at this addr\n"
1829     "  v        change to byte mode\n"
1830     "  w        change to word (2 byte) mode\n"
1831     "  l        change to long (4 byte) mode\n"
1832     "  u        change to doubleword (8 byte) mode\n"
1833     "  m addr   change current addr\n"
1834     "  n        toggle no-read flag\n"
1835     "  r        toggle byte reverse flag\n"
1836     "  < count  back up count bytes\n"
1837     "  > count  skip forward count bytes\n"
1838     "  x        exit this mode\n"
1839     "";
1840 
1841 static void
memex(void)1842 memex(void)
1843 {
1844 	int cmd, inc, i, nslash;
1845 	unsigned long n;
1846 	unsigned char val[16];
1847 
1848 	scanhex((void *)&adrs);
1849 	cmd = skipbl();
1850 	if (cmd == '?') {
1851 		printf(memex_help_string);
1852 		return;
1853 	} else {
1854 		termch = cmd;
1855 	}
1856 	last_cmd = "m\n";
1857 	while ((cmd = skipbl()) != '\n') {
1858 		switch( cmd ){
1859 		case 'b':	size = 1;	break;
1860 		case 'w':	size = 2;	break;
1861 		case 'l':	size = 4;	break;
1862 		case 'd':	size = 8;	break;
1863 		case 'r': 	brev = !brev;	break;
1864 		case 'n':	mnoread = 1;	break;
1865 		case '.':	mnoread = 0;	break;
1866 		}
1867 	}
1868 	if( size <= 0 )
1869 		size = 1;
1870 	else if( size > 8 )
1871 		size = 8;
1872 	for(;;){
1873 		if (!mnoread)
1874 			n = mread(adrs, val, size);
1875 		printf(REG"%c", adrs, brev? 'r': ' ');
1876 		if (!mnoread) {
1877 			if (brev)
1878 				byterev(val, size);
1879 			putchar(' ');
1880 			for (i = 0; i < n; ++i)
1881 				printf("%.2x", val[i]);
1882 			for (; i < size; ++i)
1883 				printf("%s", fault_chars[fault_type]);
1884 		}
1885 		putchar(' ');
1886 		inc = size;
1887 		nslash = 0;
1888 		for(;;){
1889 			if( scanhex(&n) ){
1890 				for (i = 0; i < size; ++i)
1891 					val[i] = n >> (i * 8);
1892 				if (!brev)
1893 					byterev(val, size);
1894 				mwrite(adrs, val, size);
1895 				inc = size;
1896 			}
1897 			cmd = skipbl();
1898 			if (cmd == '\n')
1899 				break;
1900 			inc = 0;
1901 			switch (cmd) {
1902 			case '\'':
1903 				for(;;){
1904 					n = inchar();
1905 					if( n == '\\' )
1906 						n = bsesc();
1907 					else if( n == '\'' )
1908 						break;
1909 					for (i = 0; i < size; ++i)
1910 						val[i] = n >> (i * 8);
1911 					if (!brev)
1912 						byterev(val, size);
1913 					mwrite(adrs, val, size);
1914 					adrs += size;
1915 				}
1916 				adrs -= size;
1917 				inc = size;
1918 				break;
1919 			case ',':
1920 				adrs += size;
1921 				break;
1922 			case '.':
1923 				mnoread = 0;
1924 				break;
1925 			case ';':
1926 				break;
1927 			case 'x':
1928 			case EOF:
1929 				scannl();
1930 				return;
1931 			case 'b':
1932 			case 'v':
1933 				size = 1;
1934 				break;
1935 			case 'w':
1936 				size = 2;
1937 				break;
1938 			case 'l':
1939 				size = 4;
1940 				break;
1941 			case 'u':
1942 				size = 8;
1943 				break;
1944 			case '^':
1945 				adrs -= size;
1946 				break;
1947 				break;
1948 			case '/':
1949 				if (nslash > 0)
1950 					adrs -= 1 << nslash;
1951 				else
1952 					nslash = 0;
1953 				nslash += 4;
1954 				adrs += 1 << nslash;
1955 				break;
1956 			case '\\':
1957 				if (nslash < 0)
1958 					adrs += 1 << -nslash;
1959 				else
1960 					nslash = 0;
1961 				nslash -= 4;
1962 				adrs -= 1 << -nslash;
1963 				break;
1964 			case 'm':
1965 				scanhex((void *)&adrs);
1966 				break;
1967 			case 'n':
1968 				mnoread = 1;
1969 				break;
1970 			case 'r':
1971 				brev = !brev;
1972 				break;
1973 			case '<':
1974 				n = size;
1975 				scanhex(&n);
1976 				adrs -= n;
1977 				break;
1978 			case '>':
1979 				n = size;
1980 				scanhex(&n);
1981 				adrs += n;
1982 				break;
1983 			case '?':
1984 				printf(memex_subcmd_help_string);
1985 				break;
1986 			}
1987 		}
1988 		adrs += inc;
1989 	}
1990 }
1991 
1992 static int
bsesc(void)1993 bsesc(void)
1994 {
1995 	int c;
1996 
1997 	c = inchar();
1998 	switch( c ){
1999 	case 'n':	c = '\n';	break;
2000 	case 'r':	c = '\r';	break;
2001 	case 'b':	c = '\b';	break;
2002 	case 't':	c = '\t';	break;
2003 	}
2004 	return c;
2005 }
2006 
xmon_rawdump(unsigned long adrs,long ndump)2007 static void xmon_rawdump (unsigned long adrs, long ndump)
2008 {
2009 	long n, m, r, nr;
2010 	unsigned char temp[16];
2011 
2012 	for (n = ndump; n > 0;) {
2013 		r = n < 16? n: 16;
2014 		nr = mread(adrs, temp, r);
2015 		adrs += nr;
2016 		for (m = 0; m < r; ++m) {
2017 			if (m < nr)
2018 				printf("%.2x", temp[m]);
2019 			else
2020 				printf("%s", fault_chars[fault_type]);
2021 		}
2022 		n -= r;
2023 		if (nr < r)
2024 			break;
2025 	}
2026 	printf("\n");
2027 }
2028 
2029 #define isxdigit(c)	(('0' <= (c) && (c) <= '9') \
2030 			 || ('a' <= (c) && (c) <= 'f') \
2031 			 || ('A' <= (c) && (c) <= 'F'))
2032 static void
dump(void)2033 dump(void)
2034 {
2035 	int c;
2036 
2037 	c = inchar();
2038 	if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
2039 		termch = c;
2040 	scanhex((void *)&adrs);
2041 	if (termch != '\n')
2042 		termch = 0;
2043 	if (c == 'i') {
2044 		scanhex(&nidump);
2045 		if (nidump == 0)
2046 			nidump = 16;
2047 		else if (nidump > MAX_DUMP)
2048 			nidump = MAX_DUMP;
2049 		adrs += ppc_inst_dump(adrs, nidump, 1);
2050 		last_cmd = "di\n";
2051 	} else if (c == 'l') {
2052 		dump_log_buf();
2053 	} else if (c == 'r') {
2054 		scanhex(&ndump);
2055 		if (ndump == 0)
2056 			ndump = 64;
2057 		xmon_rawdump(adrs, ndump);
2058 		adrs += ndump;
2059 		last_cmd = "dr\n";
2060 	} else {
2061 		scanhex(&ndump);
2062 		if (ndump == 0)
2063 			ndump = 64;
2064 		else if (ndump > MAX_DUMP)
2065 			ndump = MAX_DUMP;
2066 		prdump(adrs, ndump);
2067 		adrs += ndump;
2068 		last_cmd = "d\n";
2069 	}
2070 }
2071 
2072 static void
prdump(unsigned long adrs,long ndump)2073 prdump(unsigned long adrs, long ndump)
2074 {
2075 	long n, m, c, r, nr;
2076 	unsigned char temp[16];
2077 
2078 	for (n = ndump; n > 0;) {
2079 		printf(REG, adrs);
2080 		putchar(' ');
2081 		r = n < 16? n: 16;
2082 		nr = mread(adrs, temp, r);
2083 		adrs += nr;
2084 		for (m = 0; m < r; ++m) {
2085 		        if ((m & (sizeof(long) - 1)) == 0 && m > 0)
2086 				putchar(' ');
2087 			if (m < nr)
2088 				printf("%.2x", temp[m]);
2089 			else
2090 				printf("%s", fault_chars[fault_type]);
2091 		}
2092 		for (; m < 16; ++m) {
2093 		        if ((m & (sizeof(long) - 1)) == 0)
2094 				putchar(' ');
2095 			printf("  ");
2096 		}
2097 		printf("  |");
2098 		for (m = 0; m < r; ++m) {
2099 			if (m < nr) {
2100 				c = temp[m];
2101 				putchar(' ' <= c && c <= '~'? c: '.');
2102 			} else
2103 				putchar(' ');
2104 		}
2105 		n -= r;
2106 		for (; m < 16; ++m)
2107 			putchar(' ');
2108 		printf("|\n");
2109 		if (nr < r)
2110 			break;
2111 	}
2112 }
2113 
2114 typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr);
2115 
2116 static int
generic_inst_dump(unsigned long adr,long count,int praddr,instruction_dump_func dump_func)2117 generic_inst_dump(unsigned long adr, long count, int praddr,
2118 			instruction_dump_func dump_func)
2119 {
2120 	int nr, dotted;
2121 	unsigned long first_adr;
2122 	unsigned long inst, last_inst = 0;
2123 	unsigned char val[4];
2124 
2125 	dotted = 0;
2126 	for (first_adr = adr; count > 0; --count, adr += 4) {
2127 		nr = mread(adr, val, 4);
2128 		if (nr == 0) {
2129 			if (praddr) {
2130 				const char *x = fault_chars[fault_type];
2131 				printf(REG"  %s%s%s%s\n", adr, x, x, x, x);
2132 			}
2133 			break;
2134 		}
2135 		inst = GETWORD(val);
2136 		if (adr > first_adr && inst == last_inst) {
2137 			if (!dotted) {
2138 				printf(" ...\n");
2139 				dotted = 1;
2140 			}
2141 			continue;
2142 		}
2143 		dotted = 0;
2144 		last_inst = inst;
2145 		if (praddr)
2146 			printf(REG"  %.8x", adr, inst);
2147 		printf("\t");
2148 		dump_func(inst, adr);
2149 		printf("\n");
2150 	}
2151 	return adr - first_adr;
2152 }
2153 
2154 static int
ppc_inst_dump(unsigned long adr,long count,int praddr)2155 ppc_inst_dump(unsigned long adr, long count, int praddr)
2156 {
2157 	return generic_inst_dump(adr, count, praddr, print_insn_powerpc);
2158 }
2159 
2160 void
print_address(unsigned long addr)2161 print_address(unsigned long addr)
2162 {
2163 	xmon_print_symbol(addr, "\t# ", "");
2164 }
2165 
2166 void
dump_log_buf(void)2167 dump_log_buf(void)
2168 {
2169         const unsigned long size = 128;
2170         unsigned long end, addr;
2171         unsigned char buf[size + 1];
2172 
2173         addr = 0;
2174         buf[size] = '\0';
2175 
2176         if (setjmp(bus_error_jmp) != 0) {
2177                 printf("Unable to lookup symbol __log_buf!\n");
2178                 return;
2179         }
2180 
2181         catch_memory_errors = 1;
2182         sync();
2183         addr = kallsyms_lookup_name("__log_buf");
2184 
2185         if (! addr)
2186                 printf("Symbol __log_buf not found!\n");
2187         else {
2188                 end = addr + (1 << CONFIG_LOG_BUF_SHIFT);
2189                 while (addr < end) {
2190                         if (! mread(addr, buf, size)) {
2191                                 printf("Can't read memory at address 0x%lx\n", addr);
2192                                 break;
2193                         }
2194 
2195                         printf("%s", buf);
2196 
2197                         if (strlen(buf) < size)
2198                                 break;
2199 
2200                         addr += size;
2201                 }
2202         }
2203 
2204         sync();
2205         /* wait a little while to see if we get a machine check */
2206         __delay(200);
2207         catch_memory_errors = 0;
2208 }
2209 
2210 /*
2211  * Memory operations - move, set, print differences
2212  */
2213 static unsigned long mdest;		/* destination address */
2214 static unsigned long msrc;		/* source address */
2215 static unsigned long mval;		/* byte value to set memory to */
2216 static unsigned long mcount;		/* # bytes to affect */
2217 static unsigned long mdiffs;		/* max # differences to print */
2218 
2219 static void
memops(int cmd)2220 memops(int cmd)
2221 {
2222 	scanhex((void *)&mdest);
2223 	if( termch != '\n' )
2224 		termch = 0;
2225 	scanhex((void *)(cmd == 's'? &mval: &msrc));
2226 	if( termch != '\n' )
2227 		termch = 0;
2228 	scanhex((void *)&mcount);
2229 	switch( cmd ){
2230 	case 'm':
2231 		memmove((void *)mdest, (void *)msrc, mcount);
2232 		break;
2233 	case 's':
2234 		memset((void *)mdest, mval, mcount);
2235 		break;
2236 	case 'd':
2237 		if( termch != '\n' )
2238 			termch = 0;
2239 		scanhex((void *)&mdiffs);
2240 		memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2241 		break;
2242 	}
2243 }
2244 
2245 static void
memdiffs(unsigned char * p1,unsigned char * p2,unsigned nb,unsigned maxpr)2246 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2247 {
2248 	unsigned n, prt;
2249 
2250 	prt = 0;
2251 	for( n = nb; n > 0; --n )
2252 		if( *p1++ != *p2++ )
2253 			if( ++prt <= maxpr )
2254 				printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2255 					p1[-1], p2 - 1, p2[-1]);
2256 	if( prt > maxpr )
2257 		printf("Total of %d differences\n", prt);
2258 }
2259 
2260 static unsigned mend;
2261 static unsigned mask;
2262 
2263 static void
memlocate(void)2264 memlocate(void)
2265 {
2266 	unsigned a, n;
2267 	unsigned char val[4];
2268 
2269 	last_cmd = "ml";
2270 	scanhex((void *)&mdest);
2271 	if (termch != '\n') {
2272 		termch = 0;
2273 		scanhex((void *)&mend);
2274 		if (termch != '\n') {
2275 			termch = 0;
2276 			scanhex((void *)&mval);
2277 			mask = ~0;
2278 			if (termch != '\n') termch = 0;
2279 			scanhex((void *)&mask);
2280 		}
2281 	}
2282 	n = 0;
2283 	for (a = mdest; a < mend; a += 4) {
2284 		if (mread(a, val, 4) == 4
2285 			&& ((GETWORD(val) ^ mval) & mask) == 0) {
2286 			printf("%.16x:  %.16x\n", a, GETWORD(val));
2287 			if (++n >= 10)
2288 				break;
2289 		}
2290 	}
2291 }
2292 
2293 static unsigned long mskip = 0x1000;
2294 static unsigned long mlim = 0xffffffff;
2295 
2296 static void
memzcan(void)2297 memzcan(void)
2298 {
2299 	unsigned char v;
2300 	unsigned a;
2301 	int ok, ook;
2302 
2303 	scanhex(&mdest);
2304 	if (termch != '\n') termch = 0;
2305 	scanhex(&mskip);
2306 	if (termch != '\n') termch = 0;
2307 	scanhex(&mlim);
2308 	ook = 0;
2309 	for (a = mdest; a < mlim; a += mskip) {
2310 		ok = mread(a, &v, 1);
2311 		if (ok && !ook) {
2312 			printf("%.8x .. ", a);
2313 		} else if (!ok && ook)
2314 			printf("%.8x\n", a - mskip);
2315 		ook = ok;
2316 		if (a + mskip < a)
2317 			break;
2318 	}
2319 	if (ook)
2320 		printf("%.8x\n", a - mskip);
2321 }
2322 
proccall(void)2323 static void proccall(void)
2324 {
2325 	unsigned long args[8];
2326 	unsigned long ret;
2327 	int i;
2328 	typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2329 			unsigned long, unsigned long, unsigned long,
2330 			unsigned long, unsigned long, unsigned long);
2331 	callfunc_t func;
2332 
2333 	if (!scanhex(&adrs))
2334 		return;
2335 	if (termch != '\n')
2336 		termch = 0;
2337 	for (i = 0; i < 8; ++i)
2338 		args[i] = 0;
2339 	for (i = 0; i < 8; ++i) {
2340 		if (!scanhex(&args[i]) || termch == '\n')
2341 			break;
2342 		termch = 0;
2343 	}
2344 	func = (callfunc_t) adrs;
2345 	ret = 0;
2346 	if (setjmp(bus_error_jmp) == 0) {
2347 		catch_memory_errors = 1;
2348 		sync();
2349 		ret = func(args[0], args[1], args[2], args[3],
2350 			   args[4], args[5], args[6], args[7]);
2351 		sync();
2352 		printf("return value is %x\n", ret);
2353 	} else {
2354 		printf("*** %x exception occurred\n", fault_except);
2355 	}
2356 	catch_memory_errors = 0;
2357 }
2358 
2359 /* Input scanning routines */
2360 int
skipbl(void)2361 skipbl(void)
2362 {
2363 	int c;
2364 
2365 	if( termch != 0 ){
2366 		c = termch;
2367 		termch = 0;
2368 	} else
2369 		c = inchar();
2370 	while( c == ' ' || c == '\t' )
2371 		c = inchar();
2372 	return c;
2373 }
2374 
2375 #define N_PTREGS	44
2376 static char *regnames[N_PTREGS] = {
2377 	"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2378 	"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2379 	"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2380 	"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2381 	"pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2382 #ifdef CONFIG_PPC64
2383 	"softe",
2384 #else
2385 	"mq",
2386 #endif
2387 	"trap", "dar", "dsisr", "res"
2388 };
2389 
2390 int
scanhex(unsigned long * vp)2391 scanhex(unsigned long *vp)
2392 {
2393 	int c, d;
2394 	unsigned long v;
2395 
2396 	c = skipbl();
2397 	if (c == '%') {
2398 		/* parse register name */
2399 		char regname[8];
2400 		int i;
2401 
2402 		for (i = 0; i < sizeof(regname) - 1; ++i) {
2403 			c = inchar();
2404 			if (!isalnum(c)) {
2405 				termch = c;
2406 				break;
2407 			}
2408 			regname[i] = c;
2409 		}
2410 		regname[i] = 0;
2411 		for (i = 0; i < N_PTREGS; ++i) {
2412 			if (strcmp(regnames[i], regname) == 0) {
2413 				if (xmon_regs == NULL) {
2414 					printf("regs not available\n");
2415 					return 0;
2416 				}
2417 				*vp = ((unsigned long *)xmon_regs)[i];
2418 				return 1;
2419 			}
2420 		}
2421 		printf("invalid register name '%%%s'\n", regname);
2422 		return 0;
2423 	}
2424 
2425 	/* skip leading "0x" if any */
2426 
2427 	if (c == '0') {
2428 		c = inchar();
2429 		if (c == 'x') {
2430 			c = inchar();
2431 		} else {
2432 			d = hexdigit(c);
2433 			if (d == EOF) {
2434 				termch = c;
2435 				*vp = 0;
2436 				return 1;
2437 			}
2438 		}
2439 	} else if (c == '$') {
2440 		int i;
2441 		for (i=0; i<63; i++) {
2442 			c = inchar();
2443 			if (isspace(c)) {
2444 				termch = c;
2445 				break;
2446 			}
2447 			tmpstr[i] = c;
2448 		}
2449 		tmpstr[i++] = 0;
2450 		*vp = 0;
2451 		if (setjmp(bus_error_jmp) == 0) {
2452 			catch_memory_errors = 1;
2453 			sync();
2454 			*vp = kallsyms_lookup_name(tmpstr);
2455 			sync();
2456 		}
2457 		catch_memory_errors = 0;
2458 		if (!(*vp)) {
2459 			printf("unknown symbol '%s'\n", tmpstr);
2460 			return 0;
2461 		}
2462 		return 1;
2463 	}
2464 
2465 	d = hexdigit(c);
2466 	if (d == EOF) {
2467 		termch = c;
2468 		return 0;
2469 	}
2470 	v = 0;
2471 	do {
2472 		v = (v << 4) + d;
2473 		c = inchar();
2474 		d = hexdigit(c);
2475 	} while (d != EOF);
2476 	termch = c;
2477 	*vp = v;
2478 	return 1;
2479 }
2480 
2481 static void
scannl(void)2482 scannl(void)
2483 {
2484 	int c;
2485 
2486 	c = termch;
2487 	termch = 0;
2488 	while( c != '\n' )
2489 		c = inchar();
2490 }
2491 
hexdigit(int c)2492 static int hexdigit(int c)
2493 {
2494 	if( '0' <= c && c <= '9' )
2495 		return c - '0';
2496 	if( 'A' <= c && c <= 'F' )
2497 		return c - ('A' - 10);
2498 	if( 'a' <= c && c <= 'f' )
2499 		return c - ('a' - 10);
2500 	return EOF;
2501 }
2502 
2503 void
getstring(char * s,int size)2504 getstring(char *s, int size)
2505 {
2506 	int c;
2507 
2508 	c = skipbl();
2509 	do {
2510 		if( size > 1 ){
2511 			*s++ = c;
2512 			--size;
2513 		}
2514 		c = inchar();
2515 	} while( c != ' ' && c != '\t' && c != '\n' );
2516 	termch = c;
2517 	*s = 0;
2518 }
2519 
2520 static char line[256];
2521 static char *lineptr;
2522 
2523 static void
flush_input(void)2524 flush_input(void)
2525 {
2526 	lineptr = NULL;
2527 }
2528 
2529 static int
inchar(void)2530 inchar(void)
2531 {
2532 	if (lineptr == NULL || *lineptr == 0) {
2533 		if (xmon_gets(line, sizeof(line)) == NULL) {
2534 			lineptr = NULL;
2535 			return EOF;
2536 		}
2537 		lineptr = line;
2538 	}
2539 	return *lineptr++;
2540 }
2541 
2542 static void
take_input(char * str)2543 take_input(char *str)
2544 {
2545 	lineptr = str;
2546 }
2547 
2548 
2549 static void
symbol_lookup(void)2550 symbol_lookup(void)
2551 {
2552 	int type = inchar();
2553 	unsigned long addr;
2554 	static char tmp[64];
2555 
2556 	switch (type) {
2557 	case 'a':
2558 		if (scanhex(&addr))
2559 			xmon_print_symbol(addr, ": ", "\n");
2560 		termch = 0;
2561 		break;
2562 	case 's':
2563 		getstring(tmp, 64);
2564 		if (setjmp(bus_error_jmp) == 0) {
2565 			catch_memory_errors = 1;
2566 			sync();
2567 			addr = kallsyms_lookup_name(tmp);
2568 			if (addr)
2569 				printf("%s: %lx\n", tmp, addr);
2570 			else
2571 				printf("Symbol '%s' not found.\n", tmp);
2572 			sync();
2573 		}
2574 		catch_memory_errors = 0;
2575 		termch = 0;
2576 		break;
2577 	}
2578 }
2579 
2580 
2581 /* Print an address in numeric and symbolic form (if possible) */
xmon_print_symbol(unsigned long address,const char * mid,const char * after)2582 static void xmon_print_symbol(unsigned long address, const char *mid,
2583 			      const char *after)
2584 {
2585 	char *modname;
2586 	const char *name = NULL;
2587 	unsigned long offset, size;
2588 
2589 	printf(REG, address);
2590 	if (setjmp(bus_error_jmp) == 0) {
2591 		catch_memory_errors = 1;
2592 		sync();
2593 		name = kallsyms_lookup(address, &size, &offset, &modname,
2594 				       tmpstr);
2595 		sync();
2596 		/* wait a little while to see if we get a machine check */
2597 		__delay(200);
2598 	}
2599 
2600 	catch_memory_errors = 0;
2601 
2602 	if (name) {
2603 		printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2604 		if (modname)
2605 			printf(" [%s]", modname);
2606 	}
2607 	printf("%s", after);
2608 }
2609 
2610 #ifdef CONFIG_PPC_BOOK3S_64
dump_slb(void)2611 static void dump_slb(void)
2612 {
2613 	int i;
2614 	unsigned long esid,vsid,valid;
2615 	unsigned long llp;
2616 
2617 	printf("SLB contents of cpu %x\n", smp_processor_id());
2618 
2619 	for (i = 0; i < mmu_slb_size; i++) {
2620 		asm volatile("slbmfee  %0,%1" : "=r" (esid) : "r" (i));
2621 		asm volatile("slbmfev  %0,%1" : "=r" (vsid) : "r" (i));
2622 		valid = (esid & SLB_ESID_V);
2623 		if (valid | esid | vsid) {
2624 			printf("%02d %016lx %016lx", i, esid, vsid);
2625 			if (valid) {
2626 				llp = vsid & SLB_VSID_LLP;
2627 				if (vsid & SLB_VSID_B_1T) {
2628 					printf("  1T  ESID=%9lx  VSID=%13lx LLP:%3lx \n",
2629 						GET_ESID_1T(esid),
2630 						(vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T,
2631 						llp);
2632 				} else {
2633 					printf(" 256M ESID=%9lx  VSID=%13lx LLP:%3lx \n",
2634 						GET_ESID(esid),
2635 						(vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT,
2636 						llp);
2637 				}
2638 			} else
2639 				printf("\n");
2640 		}
2641 	}
2642 }
2643 
dump_stab(void)2644 static void dump_stab(void)
2645 {
2646 	int i;
2647 	unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2648 
2649 	printf("Segment table contents of cpu %x\n", smp_processor_id());
2650 
2651 	for (i = 0; i < PAGE_SIZE/16; i++) {
2652 		unsigned long a, b;
2653 
2654 		a = *tmp++;
2655 		b = *tmp++;
2656 
2657 		if (a || b) {
2658 			printf("%03d %016lx ", i, a);
2659 			printf("%016lx\n", b);
2660 		}
2661 	}
2662 }
2663 
dump_segments(void)2664 void dump_segments(void)
2665 {
2666 	if (cpu_has_feature(CPU_FTR_SLB))
2667 		dump_slb();
2668 	else
2669 		dump_stab();
2670 }
2671 #endif
2672 
2673 #ifdef CONFIG_PPC_STD_MMU_32
dump_segments(void)2674 void dump_segments(void)
2675 {
2676 	int i;
2677 
2678 	printf("sr0-15 =");
2679 	for (i = 0; i < 16; ++i)
2680 		printf(" %x", mfsrin(i));
2681 	printf("\n");
2682 }
2683 #endif
2684 
2685 #ifdef CONFIG_44x
dump_tlb_44x(void)2686 static void dump_tlb_44x(void)
2687 {
2688 	int i;
2689 
2690 	for (i = 0; i < PPC44x_TLB_SIZE; i++) {
2691 		unsigned long w0,w1,w2;
2692 		asm volatile("tlbre  %0,%1,0" : "=r" (w0) : "r" (i));
2693 		asm volatile("tlbre  %0,%1,1" : "=r" (w1) : "r" (i));
2694 		asm volatile("tlbre  %0,%1,2" : "=r" (w2) : "r" (i));
2695 		printf("[%02x] %08x %08x %08x ", i, w0, w1, w2);
2696 		if (w0 & PPC44x_TLB_VALID) {
2697 			printf("V %08x -> %01x%08x %c%c%c%c%c",
2698 			       w0 & PPC44x_TLB_EPN_MASK,
2699 			       w1 & PPC44x_TLB_ERPN_MASK,
2700 			       w1 & PPC44x_TLB_RPN_MASK,
2701 			       (w2 & PPC44x_TLB_W) ? 'W' : 'w',
2702 			       (w2 & PPC44x_TLB_I) ? 'I' : 'i',
2703 			       (w2 & PPC44x_TLB_M) ? 'M' : 'm',
2704 			       (w2 & PPC44x_TLB_G) ? 'G' : 'g',
2705 			       (w2 & PPC44x_TLB_E) ? 'E' : 'e');
2706 		}
2707 		printf("\n");
2708 	}
2709 }
2710 #endif /* CONFIG_44x */
2711 
2712 #ifdef CONFIG_PPC_BOOK3E
dump_tlb_book3e(void)2713 static void dump_tlb_book3e(void)
2714 {
2715 	u32 mmucfg, pidmask, lpidmask;
2716 	u64 ramask;
2717 	int i, tlb, ntlbs, pidsz, lpidsz, rasz, lrat = 0;
2718 	int mmu_version;
2719 	static const char *pgsz_names[] = {
2720 		"  1K",
2721 		"  2K",
2722 		"  4K",
2723 		"  8K",
2724 		" 16K",
2725 		" 32K",
2726 		" 64K",
2727 		"128K",
2728 		"256K",
2729 		"512K",
2730 		"  1M",
2731 		"  2M",
2732 		"  4M",
2733 		"  8M",
2734 		" 16M",
2735 		" 32M",
2736 		" 64M",
2737 		"128M",
2738 		"256M",
2739 		"512M",
2740 		"  1G",
2741 		"  2G",
2742 		"  4G",
2743 		"  8G",
2744 		" 16G",
2745 		" 32G",
2746 		" 64G",
2747 		"128G",
2748 		"256G",
2749 		"512G",
2750 		"  1T",
2751 		"  2T",
2752 	};
2753 
2754 	/* Gather some infos about the MMU */
2755 	mmucfg = mfspr(SPRN_MMUCFG);
2756 	mmu_version = (mmucfg & 3) + 1;
2757 	ntlbs = ((mmucfg >> 2) & 3) + 1;
2758 	pidsz = ((mmucfg >> 6) & 0x1f) + 1;
2759 	lpidsz = (mmucfg >> 24) & 0xf;
2760 	rasz = (mmucfg >> 16) & 0x7f;
2761 	if ((mmu_version > 1) && (mmucfg & 0x10000))
2762 		lrat = 1;
2763 	printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n",
2764 	       mmu_version, ntlbs, pidsz, lpidsz, rasz);
2765 	pidmask = (1ul << pidsz) - 1;
2766 	lpidmask = (1ul << lpidsz) - 1;
2767 	ramask = (1ull << rasz) - 1;
2768 
2769 	for (tlb = 0; tlb < ntlbs; tlb++) {
2770 		u32 tlbcfg;
2771 		int nent, assoc, new_cc = 1;
2772 		printf("TLB %d:\n------\n", tlb);
2773 		switch(tlb) {
2774 		case 0:
2775 			tlbcfg = mfspr(SPRN_TLB0CFG);
2776 			break;
2777 		case 1:
2778 			tlbcfg = mfspr(SPRN_TLB1CFG);
2779 			break;
2780 		case 2:
2781 			tlbcfg = mfspr(SPRN_TLB2CFG);
2782 			break;
2783 		case 3:
2784 			tlbcfg = mfspr(SPRN_TLB3CFG);
2785 			break;
2786 		default:
2787 			printf("Unsupported TLB number !\n");
2788 			continue;
2789 		}
2790 		nent = tlbcfg & 0xfff;
2791 		assoc = (tlbcfg >> 24) & 0xff;
2792 		for (i = 0; i < nent; i++) {
2793 			u32 mas0 = MAS0_TLBSEL(tlb);
2794 			u32 mas1 = MAS1_TSIZE(BOOK3E_PAGESZ_4K);
2795 			u64 mas2 = 0;
2796 			u64 mas7_mas3;
2797 			int esel = i, cc = i;
2798 
2799 			if (assoc != 0) {
2800 				cc = i / assoc;
2801 				esel = i % assoc;
2802 				mas2 = cc * 0x1000;
2803 			}
2804 
2805 			mas0 |= MAS0_ESEL(esel);
2806 			mtspr(SPRN_MAS0, mas0);
2807 			mtspr(SPRN_MAS1, mas1);
2808 			mtspr(SPRN_MAS2, mas2);
2809 			asm volatile("tlbre  0,0,0" : : : "memory");
2810 			mas1 = mfspr(SPRN_MAS1);
2811 			mas2 = mfspr(SPRN_MAS2);
2812 			mas7_mas3 = mfspr(SPRN_MAS7_MAS3);
2813 			if (assoc && (i % assoc) == 0)
2814 				new_cc = 1;
2815 			if (!(mas1 & MAS1_VALID))
2816 				continue;
2817 			if (assoc == 0)
2818 				printf("%04x- ", i);
2819 			else if (new_cc)
2820 				printf("%04x-%c", cc, 'A' + esel);
2821 			else
2822 				printf("    |%c", 'A' + esel);
2823 			new_cc = 0;
2824 			printf(" %016llx %04x %s %c%c AS%c",
2825 			       mas2 & ~0x3ffull,
2826 			       (mas1 >> 16) & 0x3fff,
2827 			       pgsz_names[(mas1 >> 7) & 0x1f],
2828 			       mas1 & MAS1_IND ? 'I' : ' ',
2829 			       mas1 & MAS1_IPROT ? 'P' : ' ',
2830 			       mas1 & MAS1_TS ? '1' : '0');
2831 			printf(" %c%c%c%c%c%c%c",
2832 			       mas2 & MAS2_X0 ? 'a' : ' ',
2833 			       mas2 & MAS2_X1 ? 'v' : ' ',
2834 			       mas2 & MAS2_W  ? 'w' : ' ',
2835 			       mas2 & MAS2_I  ? 'i' : ' ',
2836 			       mas2 & MAS2_M  ? 'm' : ' ',
2837 			       mas2 & MAS2_G  ? 'g' : ' ',
2838 			       mas2 & MAS2_E  ? 'e' : ' ');
2839 			printf(" %016llx", mas7_mas3 & ramask & ~0x7ffull);
2840 			if (mas1 & MAS1_IND)
2841 				printf(" %s\n",
2842 				       pgsz_names[(mas7_mas3 >> 1) & 0x1f]);
2843 			else
2844 				printf(" U%c%c%c S%c%c%c\n",
2845 				       mas7_mas3 & MAS3_UX ? 'x' : ' ',
2846 				       mas7_mas3 & MAS3_UW ? 'w' : ' ',
2847 				       mas7_mas3 & MAS3_UR ? 'r' : ' ',
2848 				       mas7_mas3 & MAS3_SX ? 'x' : ' ',
2849 				       mas7_mas3 & MAS3_SW ? 'w' : ' ',
2850 				       mas7_mas3 & MAS3_SR ? 'r' : ' ');
2851 		}
2852 	}
2853 }
2854 #endif /* CONFIG_PPC_BOOK3E */
2855 
xmon_init(int enable)2856 static void xmon_init(int enable)
2857 {
2858 #ifdef CONFIG_PPC_ISERIES
2859 	if (firmware_has_feature(FW_FEATURE_ISERIES))
2860 		return;
2861 #endif
2862 	if (enable) {
2863 		__debugger = xmon;
2864 		__debugger_ipi = xmon_ipi;
2865 		__debugger_bpt = xmon_bpt;
2866 		__debugger_sstep = xmon_sstep;
2867 		__debugger_iabr_match = xmon_iabr_match;
2868 		__debugger_dabr_match = xmon_dabr_match;
2869 		__debugger_fault_handler = xmon_fault_handler;
2870 	} else {
2871 		__debugger = NULL;
2872 		__debugger_ipi = NULL;
2873 		__debugger_bpt = NULL;
2874 		__debugger_sstep = NULL;
2875 		__debugger_iabr_match = NULL;
2876 		__debugger_dabr_match = NULL;
2877 		__debugger_fault_handler = NULL;
2878 	}
2879 	xmon_map_scc();
2880 }
2881 
2882 #ifdef CONFIG_MAGIC_SYSRQ
sysrq_handle_xmon(int key)2883 static void sysrq_handle_xmon(int key)
2884 {
2885 	/* ensure xmon is enabled */
2886 	xmon_init(1);
2887 	debugger(get_irq_regs());
2888 }
2889 
2890 static struct sysrq_key_op sysrq_xmon_op = {
2891 	.handler =	sysrq_handle_xmon,
2892 	.help_msg =	"Xmon",
2893 	.action_msg =	"Entering xmon",
2894 };
2895 
setup_xmon_sysrq(void)2896 static int __init setup_xmon_sysrq(void)
2897 {
2898 #ifdef CONFIG_PPC_ISERIES
2899 	if (firmware_has_feature(FW_FEATURE_ISERIES))
2900 		return 0;
2901 #endif
2902 	register_sysrq_key('x', &sysrq_xmon_op);
2903 	return 0;
2904 }
2905 __initcall(setup_xmon_sysrq);
2906 #endif /* CONFIG_MAGIC_SYSRQ */
2907 
2908 static int __initdata xmon_early, xmon_off;
2909 
early_parse_xmon(char * p)2910 static int __init early_parse_xmon(char *p)
2911 {
2912 	if (!p || strncmp(p, "early", 5) == 0) {
2913 		/* just "xmon" is equivalent to "xmon=early" */
2914 		xmon_init(1);
2915 		xmon_early = 1;
2916 	} else if (strncmp(p, "on", 2) == 0)
2917 		xmon_init(1);
2918 	else if (strncmp(p, "off", 3) == 0)
2919 		xmon_off = 1;
2920 	else if (strncmp(p, "nobt", 4) == 0)
2921 		xmon_no_auto_backtrace = 1;
2922 	else
2923 		return 1;
2924 
2925 	return 0;
2926 }
2927 early_param("xmon", early_parse_xmon);
2928 
xmon_setup(void)2929 void __init xmon_setup(void)
2930 {
2931 #ifdef CONFIG_XMON_DEFAULT
2932 	if (!xmon_off)
2933 		xmon_init(1);
2934 #endif
2935 	if (xmon_early)
2936 		debugger(NULL);
2937 }
2938 
2939 #ifdef CONFIG_SPU_BASE
2940 
2941 struct spu_info {
2942 	struct spu *spu;
2943 	u64 saved_mfc_sr1_RW;
2944 	u32 saved_spu_runcntl_RW;
2945 	unsigned long dump_addr;
2946 	u8 stopped_ok;
2947 };
2948 
2949 #define XMON_NUM_SPUS	16	/* Enough for current hardware */
2950 
2951 static struct spu_info spu_info[XMON_NUM_SPUS];
2952 
xmon_register_spus(struct list_head * list)2953 void xmon_register_spus(struct list_head *list)
2954 {
2955 	struct spu *spu;
2956 
2957 	list_for_each_entry(spu, list, full_list) {
2958 		if (spu->number >= XMON_NUM_SPUS) {
2959 			WARN_ON(1);
2960 			continue;
2961 		}
2962 
2963 		spu_info[spu->number].spu = spu;
2964 		spu_info[spu->number].stopped_ok = 0;
2965 		spu_info[spu->number].dump_addr = (unsigned long)
2966 				spu_info[spu->number].spu->local_store;
2967 	}
2968 }
2969 
stop_spus(void)2970 static void stop_spus(void)
2971 {
2972 	struct spu *spu;
2973 	int i;
2974 	u64 tmp;
2975 
2976 	for (i = 0; i < XMON_NUM_SPUS; i++) {
2977 		if (!spu_info[i].spu)
2978 			continue;
2979 
2980 		if (setjmp(bus_error_jmp) == 0) {
2981 			catch_memory_errors = 1;
2982 			sync();
2983 
2984 			spu = spu_info[i].spu;
2985 
2986 			spu_info[i].saved_spu_runcntl_RW =
2987 				in_be32(&spu->problem->spu_runcntl_RW);
2988 
2989 			tmp = spu_mfc_sr1_get(spu);
2990 			spu_info[i].saved_mfc_sr1_RW = tmp;
2991 
2992 			tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
2993 			spu_mfc_sr1_set(spu, tmp);
2994 
2995 			sync();
2996 			__delay(200);
2997 
2998 			spu_info[i].stopped_ok = 1;
2999 
3000 			printf("Stopped spu %.2d (was %s)\n", i,
3001 					spu_info[i].saved_spu_runcntl_RW ?
3002 					"running" : "stopped");
3003 		} else {
3004 			catch_memory_errors = 0;
3005 			printf("*** Error stopping spu %.2d\n", i);
3006 		}
3007 		catch_memory_errors = 0;
3008 	}
3009 }
3010 
restart_spus(void)3011 static void restart_spus(void)
3012 {
3013 	struct spu *spu;
3014 	int i;
3015 
3016 	for (i = 0; i < XMON_NUM_SPUS; i++) {
3017 		if (!spu_info[i].spu)
3018 			continue;
3019 
3020 		if (!spu_info[i].stopped_ok) {
3021 			printf("*** Error, spu %d was not successfully stopped"
3022 					", not restarting\n", i);
3023 			continue;
3024 		}
3025 
3026 		if (setjmp(bus_error_jmp) == 0) {
3027 			catch_memory_errors = 1;
3028 			sync();
3029 
3030 			spu = spu_info[i].spu;
3031 			spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
3032 			out_be32(&spu->problem->spu_runcntl_RW,
3033 					spu_info[i].saved_spu_runcntl_RW);
3034 
3035 			sync();
3036 			__delay(200);
3037 
3038 			printf("Restarted spu %.2d\n", i);
3039 		} else {
3040 			catch_memory_errors = 0;
3041 			printf("*** Error restarting spu %.2d\n", i);
3042 		}
3043 		catch_memory_errors = 0;
3044 	}
3045 }
3046 
3047 #define DUMP_WIDTH	23
3048 #define DUMP_VALUE(format, field, value)				\
3049 do {									\
3050 	if (setjmp(bus_error_jmp) == 0) {				\
3051 		catch_memory_errors = 1;				\
3052 		sync();							\
3053 		printf("  %-*s = "format"\n", DUMP_WIDTH,		\
3054 				#field, value);				\
3055 		sync();							\
3056 		__delay(200);						\
3057 	} else {							\
3058 		catch_memory_errors = 0;				\
3059 		printf("  %-*s = *** Error reading field.\n",		\
3060 					DUMP_WIDTH, #field);		\
3061 	}								\
3062 	catch_memory_errors = 0;					\
3063 } while (0)
3064 
3065 #define DUMP_FIELD(obj, format, field)	\
3066 	DUMP_VALUE(format, field, obj->field)
3067 
dump_spu_fields(struct spu * spu)3068 static void dump_spu_fields(struct spu *spu)
3069 {
3070 	printf("Dumping spu fields at address %p:\n", spu);
3071 
3072 	DUMP_FIELD(spu, "0x%x", number);
3073 	DUMP_FIELD(spu, "%s", name);
3074 	DUMP_FIELD(spu, "0x%lx", local_store_phys);
3075 	DUMP_FIELD(spu, "0x%p", local_store);
3076 	DUMP_FIELD(spu, "0x%lx", ls_size);
3077 	DUMP_FIELD(spu, "0x%x", node);
3078 	DUMP_FIELD(spu, "0x%lx", flags);
3079 	DUMP_FIELD(spu, "%d", class_0_pending);
3080 	DUMP_FIELD(spu, "0x%lx", class_0_dar);
3081 	DUMP_FIELD(spu, "0x%lx", class_1_dar);
3082 	DUMP_FIELD(spu, "0x%lx", class_1_dsisr);
3083 	DUMP_FIELD(spu, "0x%lx", irqs[0]);
3084 	DUMP_FIELD(spu, "0x%lx", irqs[1]);
3085 	DUMP_FIELD(spu, "0x%lx", irqs[2]);
3086 	DUMP_FIELD(spu, "0x%x", slb_replace);
3087 	DUMP_FIELD(spu, "%d", pid);
3088 	DUMP_FIELD(spu, "0x%p", mm);
3089 	DUMP_FIELD(spu, "0x%p", ctx);
3090 	DUMP_FIELD(spu, "0x%p", rq);
3091 	DUMP_FIELD(spu, "0x%p", timestamp);
3092 	DUMP_FIELD(spu, "0x%lx", problem_phys);
3093 	DUMP_FIELD(spu, "0x%p", problem);
3094 	DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
3095 			in_be32(&spu->problem->spu_runcntl_RW));
3096 	DUMP_VALUE("0x%x", problem->spu_status_R,
3097 			in_be32(&spu->problem->spu_status_R));
3098 	DUMP_VALUE("0x%x", problem->spu_npc_RW,
3099 			in_be32(&spu->problem->spu_npc_RW));
3100 	DUMP_FIELD(spu, "0x%p", priv2);
3101 	DUMP_FIELD(spu, "0x%p", pdata);
3102 }
3103 
3104 int
spu_inst_dump(unsigned long adr,long count,int praddr)3105 spu_inst_dump(unsigned long adr, long count, int praddr)
3106 {
3107 	return generic_inst_dump(adr, count, praddr, print_insn_spu);
3108 }
3109 
dump_spu_ls(unsigned long num,int subcmd)3110 static void dump_spu_ls(unsigned long num, int subcmd)
3111 {
3112 	unsigned long offset, addr, ls_addr;
3113 
3114 	if (setjmp(bus_error_jmp) == 0) {
3115 		catch_memory_errors = 1;
3116 		sync();
3117 		ls_addr = (unsigned long)spu_info[num].spu->local_store;
3118 		sync();
3119 		__delay(200);
3120 	} else {
3121 		catch_memory_errors = 0;
3122 		printf("*** Error: accessing spu info for spu %d\n", num);
3123 		return;
3124 	}
3125 	catch_memory_errors = 0;
3126 
3127 	if (scanhex(&offset))
3128 		addr = ls_addr + offset;
3129 	else
3130 		addr = spu_info[num].dump_addr;
3131 
3132 	if (addr >= ls_addr + LS_SIZE) {
3133 		printf("*** Error: address outside of local store\n");
3134 		return;
3135 	}
3136 
3137 	switch (subcmd) {
3138 	case 'i':
3139 		addr += spu_inst_dump(addr, 16, 1);
3140 		last_cmd = "sdi\n";
3141 		break;
3142 	default:
3143 		prdump(addr, 64);
3144 		addr += 64;
3145 		last_cmd = "sd\n";
3146 		break;
3147 	}
3148 
3149 	spu_info[num].dump_addr = addr;
3150 }
3151 
do_spu_cmd(void)3152 static int do_spu_cmd(void)
3153 {
3154 	static unsigned long num = 0;
3155 	int cmd, subcmd = 0;
3156 
3157 	cmd = inchar();
3158 	switch (cmd) {
3159 	case 's':
3160 		stop_spus();
3161 		break;
3162 	case 'r':
3163 		restart_spus();
3164 		break;
3165 	case 'd':
3166 		subcmd = inchar();
3167 		if (isxdigit(subcmd) || subcmd == '\n')
3168 			termch = subcmd;
3169 	case 'f':
3170 		scanhex(&num);
3171 		if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
3172 			printf("*** Error: invalid spu number\n");
3173 			return 0;
3174 		}
3175 
3176 		switch (cmd) {
3177 		case 'f':
3178 			dump_spu_fields(spu_info[num].spu);
3179 			break;
3180 		default:
3181 			dump_spu_ls(num, subcmd);
3182 			break;
3183 		}
3184 
3185 		break;
3186 	default:
3187 		return -1;
3188 	}
3189 
3190 	return 0;
3191 }
3192 #else /* ! CONFIG_SPU_BASE */
do_spu_cmd(void)3193 static int do_spu_cmd(void)
3194 {
3195 	return -1;
3196 }
3197 #endif
3198