11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Routines providing a simple monitor for use on the PowerMac. 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras * Copyright (C) 1996-2005 Paul Mackerras. 5476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman * Copyright (C) 2001 PPC64 Team, IBM Corp 6476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman * Copyrignt (C) 2006 Michael Ellerman, IBM Corp 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is free software; you can redistribute it and/or 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * modify it under the terms of the GNU General Public License 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * as published by the Free Software Foundation; either version 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2 of the License, or (at your option) any later version. 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/errno.h> 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/sched.h> 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/smp.h> 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mm.h> 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/reboot.h> 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/delay.h> 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kallsyms.h> 20ca5dd3954a62dc14c2afff1c34b3b5d8dc74f777Michael Ellerman#include <linux/kmsg_dump.h> 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/cpumask.h> 224b16f8e2d6d64249f0ed3ca7fe2a319d0dde2719Paul Gortmaker#include <linux/export.h> 23fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras#include <linux/sysrq.h> 244694ca02d19f42f5fd0b62cc2d0c7d3e5a0eef47Andrew Morton#include <linux/interrupt.h> 257d12e780e003f93433d49ce78cfedf4b4c52adc5David Howells#include <linux/irq.h> 2673c9ceab40b1269d6195e556773167c078ac8311Jeremy Fitzhardinge#include <linux/bug.h> 27a71d64b4dc4067808549935583d984c7fc9ea647Anton Blanchard#include <linux/nmi.h> 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/ptrace.h> 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/string.h> 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/prom.h> 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/machdep.h> 33f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#include <asm/xmon.h> 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/processor.h> 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/pgtable.h> 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/mmu.h> 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/mmu_context.h> 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/cputable.h> 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/rtas.h> 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/sstep.h> 41f583ffce1aac783fd16d5d75cd69ac5ebb8f4933Paul Mackerras#include <asm/irq_regs.h> 42ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman#include <asm/spu.h> 43ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman#include <asm/spu_priv1.h> 44c3b75bd7bbf4a0438dc140033b80657995fd30edMichael Neuling#include <asm/setjmp.h> 45322b439455ea62e6480e300c77b258e872896381Anton Vorontsov#include <asm/reg.h> 46ae3a197e3d0bfe3f4bf1693723e82dc018c096f3David Howells#include <asm/debug.h> 479422de3e953d0e60eb95f5430a9dd803eec1c6d7Michael Neuling#include <asm/hw_breakpoint.h> 48f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras 49f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#ifdef CONFIG_PPC64 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/hvcall.h> 51f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#include <asm/paca.h> 52f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#endif 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "nonstdio.h" 55e0426047cb684842700f0098f74842a38260dbaeMichael Ellerman#include "dis-asm.h" 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_SMP 581c8950ff87de950a3b6ccfb26650fc0a56278836Michael Ellermanstatic cpumask_t cpus_in_xmon = CPU_MASK_NONE; 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long xmon_taken = 1; 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int xmon_owner; 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int xmon_gate; 62ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman#else 63ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman#define xmon_owner 0 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* CONFIG_SMP */ 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 665be3492f972b73051ead7ecbac6fb9efd1e8e0ecAnton Blanchardstatic unsigned long in_xmon __read_mostly = 0; 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long adrs; 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int size = 1; 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MAX_DUMP (128 * 1024) 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long ndump = 64; 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long nidump = 16; 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long ncsum = 4096; 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int termch; 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char tmpstr[128]; 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic long bus_error_jmp[JMP_BUF_LEN]; 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int catch_memory_errors; 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic long *xmon_fault_jmp[NR_CPUS]; 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Breakpoint stuff */ 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct bpt { 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long address; 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int instr[2]; 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds atomic_t ref_count; 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int enabled; 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long pad; 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Bits in bpt.enabled */ 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define BP_IABR_TE 1 /* IABR translation enabled */ 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define BP_IABR 2 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define BP_TRAP 8 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define BP_DABR 0x10 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define NBPTS 256 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct bpt bpts[NBPTS]; 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct bpt dabr; 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct bpt *iabr; 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned bpinstr = 0x7fe00008; /* trap */ 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define BP_NUM(bp) ((bp) - bpts + 1) 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Prototypes */ 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int cmds(struct pt_regs *); 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int mread(unsigned long, void *, int); 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int mwrite(unsigned long, void *, int); 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int handle_fault(struct pt_regs *); 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void byterev(unsigned char *, int); 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void memex(void); 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int bsesc(void); 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void dump(void); 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void prdump(unsigned long, long); 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int ppc_inst_dump(unsigned long, long, int); 115f312deb4cd0c88196edf6dab192b7d42514398d6Vinay Sridharstatic void dump_log_buf(void); 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void backtrace(struct pt_regs *); 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void excprint(struct pt_regs *); 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void prregs(struct pt_regs *); 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void memops(int); 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void memlocate(void); 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void memzcan(void); 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned); 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint skipbl(void); 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint scanhex(unsigned long *valp); 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void scannl(void); 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int hexdigit(int); 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid getstring(char *, int); 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void flush_input(void); 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int inchar(void); 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void take_input(char *); 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long read_spr(int); 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void write_spr(int, unsigned long); 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void super_regs(void); 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void remove_bpts(void); 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void insert_bpts(void); 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void remove_cpu_bpts(void); 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void insert_cpu_bpts(void); 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct bpt *at_breakpoint(unsigned long pc); 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp); 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int do_step(struct pt_regs *); 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void bpt_cmds(void); 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void cacheflush(void); 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int cpu_cmd(void); 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void csum(void); 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void bootcmds(void); 146f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerrasstatic void proccall(void); 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid dump_segments(void); 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void symbol_lookup(void); 14926c8af5f01dfb91f709cc2ba07fb650949aae13eOlaf Heringstatic void xmon_show_stack(unsigned long sp, unsigned long lr, 15026c8af5f01dfb91f709cc2ba07fb650949aae13eOlaf Hering unsigned long pc); 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void xmon_print_symbol(unsigned long address, const char *mid, 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const char *after); 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const char *getvecname(unsigned long vec); 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 155ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellermanstatic int do_spu_cmd(void); 156ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman 1575a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt#ifdef CONFIG_44x 1585a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidtstatic void dump_tlb_44x(void); 1595a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt#endif 16003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt#ifdef CONFIG_PPC_BOOK3E 16103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidtstatic void dump_tlb_book3e(void); 16203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt#endif 1635a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt 1649f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic int xmon_no_auto_backtrace; 16526c8af5f01dfb91f709cc2ba07fb650949aae13eOlaf Hering 166f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerrasextern void xmon_enter(void); 167f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerrasextern void xmon_leave(void); 168f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras 169f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#ifdef CONFIG_PPC64 170f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#define REG "%.16lx" 171f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#else 172f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#define REG "%.8lx" 173f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#endif 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17572eceef67abbe596a4e93ee79e08d9e6c35430aePhilippe Bergheaud#ifdef __LITTLE_ENDIAN__ 17672eceef67abbe596a4e93ee79e08d9e6c35430aePhilippe Bergheaud#define GETWORD(v) (((v)[3] << 24) + ((v)[2] << 16) + ((v)[1] << 8) + (v)[0]) 17772eceef67abbe596a4e93ee79e08d9e6c35430aePhilippe Bergheaud#else 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3]) 17972eceef67abbe596a4e93ee79e08d9e6c35430aePhilippe Bergheaud#endif 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define isxdigit(c) (('0' <= (c) && (c) <= '9') \ 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds || ('a' <= (c) && (c) <= 'f') \ 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds || ('A' <= (c) && (c) <= 'F')) 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define isalnum(c) (('0' <= (c) && (c) <= '9') \ 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds || ('a' <= (c) && (c) <= 'z') \ 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds || ('A' <= (c) && (c) <= 'Z')) 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0) 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char *help_string = "\ 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsCommands:\n\ 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds b show breakpoints\n\ 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bd set data breakpoint\n\ 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bi set instruction breakpoint\n\ 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bc clear breakpoint\n" 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_SMP 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "\ 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c print cpus stopped in xmon\n\ 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c# try to switch to cpu number h (in hex)\n" 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "\ 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds C checksum\n\ 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds d dump bytes\n\ 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds di dump instructions\n\ 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds df dump float values\n\ 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dd dump double values\n\ 206ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman dl dump the kernel log buffer\n" 207ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman#ifdef CONFIG_PPC64 208ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman "\ 209ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman dp[#] dump paca for current cpu, or cpu #\n\ 210ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman dpa dump paca for all possible cpus\n" 211ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman#endif 212ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman "\ 2137e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering dr dump stream of raw bytes\n\ 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e print exception information\n\ 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds f flush cache\n\ 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds la lookup symbol+offset of specified address\n\ 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ls lookup address of specified symbol\n\ 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds m examine/change memory\n\ 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mm move a block of memory\n\ 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ms set a block of memory\n\ 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds md compare two blocks of memory\n\ 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ml locate a block of memory\n\ 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mz zero a block of memory\n\ 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mi show information about memory allocation\n\ 225f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras p call a procedure\n\ 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r print registers\n\ 227ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman s single step\n" 228e055595d3e5f5233374211bc6893e5d16976df99Arnd Bergmann#ifdef CONFIG_SPU_BASE 229ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman" ss stop execution on all spus\n\ 230a898497088f46252e6750405504064e2dce53117Michael Ellerman sr restore execution on stopped spus\n\ 23124a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman sf # dump spu fields for spu # (in hex)\n\ 232c99176a230097b076c2f98e4bf963399fe114ffdMichael Ellerman sd # dump spu local store for spu # (in hex)\n\ 233af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman sdi # disassemble spu local store for spu # (in hex)\n" 234ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman#endif 235ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman" S print special registers\n\ 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds t print backtrace\n\ 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds x exit monitor and recover\n\ 238f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras X exit monitor and dont recover\n" 23979873e8df64cc124cdcad56d1d8330b3f45690bcJimi Xenidis#if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_BOOK3E) 240f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras" u dump segment table or SLB\n" 24179873e8df64cc124cdcad56d1d8330b3f45690bcJimi Xenidis#elif defined(CONFIG_PPC_STD_MMU_32) 242f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras" u dump segment registers\n" 24379873e8df64cc124cdcad56d1d8330b3f45690bcJimi Xenidis#elif defined(CONFIG_44x) || defined(CONFIG_PPC_BOOK3E) 2445a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt" u dump TLB\n" 2455a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt#endif 246f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras" ? help\n" 247f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras" zr reboot\n\ 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds zh halt\n" 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds; 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct pt_regs *xmon_regs; 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 253f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerrasstatic inline void sync(void) 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds asm volatile("sync; isync"); 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 258f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerrasstatic inline void store_inst(void *p) 259f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras{ 260f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p)); 261f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras} 262f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras 263f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerrasstatic inline void cflush(void *p) 264f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras{ 265f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p)); 266f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras} 267f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras 268f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerrasstatic inline void cinval(void *p) 269f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras{ 270f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p)); 271f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras} 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Disable surveillance (the service processor watchdog function) 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * while we are in xmon. 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * XXX we should re-enable it when we leave. :) 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SURVEILLANCE_TOKEN 9000 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void disable_surveillance(void) 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_PPC_PSERIES 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Since this can't be a module, args should end up below 4GB. */ 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds static struct rtas_args args; 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * At this point we have got all the cpus we can into 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * xmon, so there is hopefully no other cpu calling RTAS 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * at the moment, even though we don't take rtas.lock. 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If we did try to take rtas.lock there would be a 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * real possibility of deadlock. 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds args.token = rtas_token("set-indicator"); 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (args.token == RTAS_UNKNOWN_SERVICE) 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 2963b8a3c01096925a824ed3272601082289d9c23a5Laurent Dufour args.nargs = cpu_to_be32(3); 2973b8a3c01096925a824ed3272601082289d9c23a5Laurent Dufour args.nret = cpu_to_be32(1); 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds args.rets = &args.args[3]; 2993b8a3c01096925a824ed3272601082289d9c23a5Laurent Dufour args.args[0] = cpu_to_be32(SURVEILLANCE_TOKEN); 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds args.args[1] = 0; 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds args.args[2] = 0; 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enter_rtas(__pa(&args)); 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* CONFIG_PPC_PSERIES */ 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_SMP 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int xmon_speaker; 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void get_output_lock(void) 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int me = smp_processor_id() + 0x100; 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int last_speaker = 0, prev; 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds long timeout; 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (xmon_speaker == me) 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 317730efb6193f8568354fd80849612291afa9fa81eMichael Ellerman 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (;;) { 319730efb6193f8568354fd80849612291afa9fa81eMichael Ellerman last_speaker = cmpxchg(&xmon_speaker, 0, me); 320730efb6193f8568354fd80849612291afa9fa81eMichael Ellerman if (last_speaker == 0) 321730efb6193f8568354fd80849612291afa9fa81eMichael Ellerman return; 322730efb6193f8568354fd80849612291afa9fa81eMichael Ellerman 3231507589787529b0d8e2a9e66e0c6f113ecab5181Michael Ellerman /* 3241507589787529b0d8e2a9e66e0c6f113ecab5181Michael Ellerman * Wait a full second for the lock, we might be on a slow 3251507589787529b0d8e2a9e66e0c6f113ecab5181Michael Ellerman * console, but check every 100us. 3261507589787529b0d8e2a9e66e0c6f113ecab5181Michael Ellerman */ 3271507589787529b0d8e2a9e66e0c6f113ecab5181Michael Ellerman timeout = 10000; 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (xmon_speaker == last_speaker) { 3291507589787529b0d8e2a9e66e0c6f113ecab5181Michael Ellerman if (--timeout > 0) { 3301507589787529b0d8e2a9e66e0c6f113ecab5181Michael Ellerman udelay(100); 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 3321507589787529b0d8e2a9e66e0c6f113ecab5181Michael Ellerman } 3331507589787529b0d8e2a9e66e0c6f113ecab5181Michael Ellerman 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* hostile takeover */ 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds prev = cmpxchg(&xmon_speaker, last_speaker, me); 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (prev == last_speaker) 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void release_output_lock(void) 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_speaker = 0; 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3471c8950ff87de950a3b6ccfb26650fc0a56278836Michael Ellerman 3481c8950ff87de950a3b6ccfb26650fc0a56278836Michael Ellermanint cpus_are_in_xmon(void) 3491c8950ff87de950a3b6ccfb26650fc0a56278836Michael Ellerman{ 350104699c0ab473535793b5fea156adaf309afd29bKOSAKI Motohiro return !cpumask_empty(&cpus_in_xmon); 3511c8950ff87de950a3b6ccfb26650fc0a56278836Michael Ellerman} 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 354daf8f40391b2a1978ea2071c20959d91fade6b1aJosh Boyerstatic inline int unrecoverable_excp(struct pt_regs *regs) 355daf8f40391b2a1978ea2071c20959d91fade6b1aJosh Boyer{ 35608f6d6abc3eadb88f020075910e6f3a849e56690Jimi Xenidis#if defined(CONFIG_4xx) || defined(CONFIG_PPC_BOOK3E) 35766857b3a9e88ac6f6e279eaa06b84367e662c0ddJimi Xenidis /* We have no MSR_RI bit on 4xx or Book3e, so we simply return false */ 358daf8f40391b2a1978ea2071c20959d91fade6b1aJosh Boyer return 0; 359daf8f40391b2a1978ea2071c20959d91fade6b1aJosh Boyer#else 360daf8f40391b2a1978ea2071c20959d91fade6b1aJosh Boyer return ((regs->msr & MSR_RI) == 0); 361daf8f40391b2a1978ea2071c20959d91fade6b1aJosh Boyer#endif 362daf8f40391b2a1978ea2071c20959d91fade6b1aJosh Boyer} 363daf8f40391b2a1978ea2071c20959d91fade6b1aJosh Boyer 364b0da985644faa45def84ce5d8e18af6f1680f490Arnd Bergmannstatic int xmon_core(struct pt_regs *regs, int fromipi) 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int cmd = 0; 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct bpt *bp; 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds long recurse_jmp[JMP_BUF_LEN]; 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long offset; 370f13659e0b3907548402ce1f47bf866544b804260Anton Blanchard unsigned long flags; 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_SMP 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int cpu; 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int secondary; 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long timeout; 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 377f13659e0b3907548402ce1f47bf866544b804260Anton Blanchard local_irq_save(flags); 378a71d64b4dc4067808549935583d984c7fc9ea647Anton Blanchard hard_irq_disable(); 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bp = in_breakpoint_table(regs->nip, &offset); 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bp != NULL) { 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->nip = bp->address + offset; 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds atomic_dec(&bp->ref_count); 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds remove_cpu_bpts(); 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_SMP 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cpu = smp_processor_id(); 390104699c0ab473535793b5fea156adaf309afd29bKOSAKI Motohiro if (cpumask_test_cpu(cpu, &cpus_in_xmon)) { 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds get_output_lock(); 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds excprint(regs); 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("cpu 0x%x: Exception %lx %s in xmon, " 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "returning to main loop\n", 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cpu, regs->trap, getvecname(TRAP(regs))); 3965cb4cc0d8211c490537c8568001958fc76741312Haren Myneni release_output_lock(); 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds longjmp(xmon_fault_jmp[cpu], 1); 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (setjmp(recurse_jmp) != 0) { 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!in_xmon || !xmon_gate) { 4025cb4cc0d8211c490537c8568001958fc76741312Haren Myneni get_output_lock(); 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("xmon: WARNING: bad recursive fault " 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "on cpu 0x%x\n", cpu); 4055cb4cc0d8211c490537c8568001958fc76741312Haren Myneni release_output_lock(); 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto waiting; 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds secondary = !(xmon_taken && cpu == xmon_owner); 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto cmdloop; 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_fault_jmp[cpu] = recurse_jmp; 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bp = NULL; 4159f0b079320ad1cc71ad7ea4e0ed0b64cd72bbd6dMichael Ellerman if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bp = at_breakpoint(regs->nip); 417daf8f40391b2a1978ea2071c20959d91fade6b1aJosh Boyer if (bp || unrecoverable_excp(regs)) 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fromipi = 0; 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!fromipi) { 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds get_output_lock(); 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds excprint(regs); 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bp) { 424736256e4f1bc50bb8198c9b61dffd5fd0de17477Michael Ellerman printf("cpu 0x%x stopped at breakpoint 0x%lx (", 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cpu, BP_NUM(bp)); 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_print_symbol(regs->nip, " ", ")\n"); 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 428daf8f40391b2a1978ea2071c20959d91fade6b1aJosh Boyer if (unrecoverable_excp(regs)) 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("WARNING: exception is not recoverable, " 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "can't continue\n"); 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds release_output_lock(); 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 434d2b496e5e1fa7a6796534e435440eb9d3ed184ddMichael Ellerman cpumask_set_cpu(cpu, &cpus_in_xmon); 435d2b496e5e1fa7a6796534e435440eb9d3ed184ddMichael Ellerman 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds waiting: 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds secondary = 1; 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (secondary && !xmon_gate) { 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (in_xmon == 0) { 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fromipi) 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto leave; 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds secondary = test_and_set_bit(0, &in_xmon); 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds barrier(); 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!secondary && !xmon_gate) { 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* we are the first cpu to come in */ 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* interrupt other cpu(s) */ 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ncpus = num_online_cpus(); 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_owner = cpu; 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ncpus > 1) { 455e04763713286b1e00e1c2a33fe2741caf9470f2bMilton Miller smp_send_debugger_break(); 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* wait for other cpus to come in */ 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (timeout = 100000000; timeout != 0; --timeout) { 458104699c0ab473535793b5fea156adaf309afd29bKOSAKI Motohiro if (cpumask_weight(&cpus_in_xmon) >= ncpus) 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds barrier(); 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds remove_bpts(); 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds disable_surveillance(); 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* for breakpoint or single step, print the current instr. */ 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bp || TRAP(regs) == 0xd00) 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ppc_inst_dump(regs->nip, 1, 0); 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("enter ? for help\n"); 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_gate = 1; 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds barrier(); 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmdloop: 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (in_xmon) { 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (secondary) { 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cpu == xmon_owner) { 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!test_and_set_bit(0, &xmon_taken)) { 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds secondary = 0; 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* missed it */ 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (cpu == xmon_owner) 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds barrier(); 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds barrier(); 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd = cmds(regs); 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cmd != 0) { 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* exiting xmon */ 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds insert_bpts(); 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_gate = 0; 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wmb(); 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds in_xmon = 0; 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* have switched to some other cpu */ 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds secondary = 1; 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds leave: 502104699c0ab473535793b5fea156adaf309afd29bKOSAKI Motohiro cpumask_clear_cpu(cpu, &cpus_in_xmon); 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_fault_jmp[cpu] = NULL; 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* UP is simple... */ 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (in_xmon) { 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("Exception %lx %s in xmon, returning to main loop\n", 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->trap, getvecname(TRAP(regs))); 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds longjmp(xmon_fault_jmp[0], 1); 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (setjmp(recurse_jmp) == 0) { 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_fault_jmp[0] = recurse_jmp; 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds in_xmon = 1; 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds excprint(regs); 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bp = at_breakpoint(regs->nip); 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bp) { 518736256e4f1bc50bb8198c9b61dffd5fd0de17477Michael Ellerman printf("Stopped at breakpoint %lx (", BP_NUM(bp)); 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_print_symbol(regs->nip, " ", ")\n"); 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 521daf8f40391b2a1978ea2071c20959d91fade6b1aJosh Boyer if (unrecoverable_excp(regs)) 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("WARNING: exception is not recoverable, " 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "can't continue\n"); 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds remove_bpts(); 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds disable_surveillance(); 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* for breakpoint or single step, print the current instr. */ 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bp || TRAP(regs) == 0xd00) 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ppc_inst_dump(regs->nip, 1, 0); 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("enter ? for help\n"); 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd = cmds(regs); 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds insert_bpts(); 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds in_xmon = 0; 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 538cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer#ifdef CONFIG_BOOKE 539cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer if (regs->msr & MSR_DE) { 540cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer bp = at_breakpoint(regs->nip); 541cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer if (bp != NULL) { 542cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer regs->nip = (unsigned long) &bp->instr[0]; 543cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer atomic_inc(&bp->ref_count); 544cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer } 545cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer } 546cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer#else 5479f0b079320ad1cc71ad7ea4e0ed0b64cd72bbd6dMichael Ellerman if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) { 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bp = at_breakpoint(regs->nip); 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bp != NULL) { 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int stepped = emulate_step(regs, bp->instr[0]); 5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (stepped == 0) { 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->nip = (unsigned long) &bp->instr[0]; 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds atomic_inc(&bp->ref_count); 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (stepped < 0) { 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("Couldn't single-step %s instruction\n", 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (IS_RFID(bp->instr[0])? "rfid": "mtmsrd")); 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 560cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer#endif 5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds insert_cpu_bpts(); 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 563a71d64b4dc4067808549935583d984c7fc9ea647Anton Blanchard touch_nmi_watchdog(); 564f13659e0b3907548402ce1f47bf866544b804260Anton Blanchard local_irq_restore(flags); 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5660a730ae59960165ae50de3284fb50316d1755d98Paul Mackerras return cmd != 'X' && cmd != EOF; 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint xmon(struct pt_regs *excp) 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pt_regs regs; 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (excp == NULL) { 574322b439455ea62e6480e300c77b258e872896381Anton Vorontsov ppc_save_regs(®s); 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds excp = ®s; 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 577ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return xmon_core(excp, 0); 5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 580f78541dcec327b0c46b150ee7d727f3db80275c4Paul MackerrasEXPORT_SYMBOL(xmon); 581f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras 582f583ffce1aac783fd16d5d75cd69ac5ebb8f4933Paul Mackerrasirqreturn_t xmon_irq(int irq, void *d) 583f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras{ 584f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras unsigned long flags; 585f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras local_irq_save(flags); 586f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras printf("Keyboard interrupt\n"); 587f583ffce1aac783fd16d5d75cd69ac5ebb8f4933Paul Mackerras xmon(get_irq_regs()); 588f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras local_irq_restore(flags); 589f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras return IRQ_HANDLED; 590f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras} 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 592b0da985644faa45def84ce5d8e18af6f1680f490Arnd Bergmannstatic int xmon_bpt(struct pt_regs *regs) 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct bpt *bp; 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long offset; 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5979f0b079320ad1cc71ad7ea4e0ed0b64cd72bbd6dMichael Ellerman if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT)) 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Are we at the trap at bp->instr[1] for some bp? */ 6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bp = in_breakpoint_table(regs->nip, &offset); 6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bp != NULL && offset == 4) { 6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->nip = bp->address + 4; 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds atomic_dec(&bp->ref_count); 6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Are we at a breakpoint? */ 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bp = at_breakpoint(regs->nip); 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!bp) 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_core(regs, 0); 6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 618b0da985644faa45def84ce5d8e18af6f1680f490Arnd Bergmannstatic int xmon_sstep(struct pt_regs *regs) 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (user_mode(regs)) 6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_core(regs, 0); 6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6269422de3e953d0e60eb95f5430a9dd803eec1c6d7Michael Neulingstatic int xmon_break_match(struct pt_regs *regs) 6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6289f0b079320ad1cc71ad7ea4e0ed0b64cd72bbd6dMichael Ellerman if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT)) 6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 630fd9648dff6f9797ecc509bcd181706a274dc074dAnton Blanchard if (dabr.enabled == 0) 631fd9648dff6f9797ecc509bcd181706a274dc074dAnton Blanchard return 0; 6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_core(regs, 0); 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 636b0da985644faa45def84ce5d8e18af6f1680f490Arnd Bergmannstatic int xmon_iabr_match(struct pt_regs *regs) 6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6389f0b079320ad1cc71ad7ea4e0ed0b64cd72bbd6dMichael Ellerman if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT)) 6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 6409f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellerman if (iabr == NULL) 6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_core(regs, 0); 6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 646b0da985644faa45def84ce5d8e18af6f1680f490Arnd Bergmannstatic int xmon_ipi(struct pt_regs *regs) 6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_SMP 649104699c0ab473535793b5fea156adaf309afd29bKOSAKI Motohiro if (in_xmon && !cpumask_test_cpu(smp_processor_id(), &cpus_in_xmon)) 6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_core(regs, 1); 6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 655b0da985644faa45def84ce5d8e18af6f1680f490Arnd Bergmannstatic int xmon_fault_handler(struct pt_regs *regs) 6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct bpt *bp; 6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long offset; 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (in_xmon && catch_memory_errors) 6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds handle_fault(regs); /* doesn't return */ 6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6639f0b079320ad1cc71ad7ea4e0ed0b64cd72bbd6dMichael Ellerman if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) { 6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bp = in_breakpoint_table(regs->nip, &offset); 6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bp != NULL) { 6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->nip = bp->address + offset; 6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds atomic_dec(&bp->ref_count); 6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct bpt *at_breakpoint(unsigned long pc) 6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct bpt *bp; 6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bp = bpts; 6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < NBPTS; ++i, ++bp) 6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bp->enabled && pc == bp->address) 6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return bp; 6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp) 6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long off; 6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds off = nip - (unsigned long) bpts; 6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (off >= sizeof(bpts)) 6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds off %= sizeof(struct bpt); 6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (off != offsetof(struct bpt, instr[0]) 6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds && off != offsetof(struct bpt, instr[1])) 6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *offp = off - offsetof(struct bpt, instr[0]); 6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (struct bpt *) (nip - off); 6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct bpt *new_breakpoint(unsigned long a) 7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct bpt *bp; 7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds a &= ~3UL; 7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bp = at_breakpoint(a); 7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bp) 7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return bp; 7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (bp = bpts; bp < &bpts[NBPTS]; ++bp) { 7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!bp->enabled && atomic_read(&bp->ref_count) == 0) { 7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bp->address = a; 7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bp->instr[1] = bpinstr; 7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds store_inst(&bp->instr[1]); 7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return bp; 7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("Sorry, no free breakpoints. Please clear one first.\n"); 7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void insert_bpts(void) 7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct bpt *bp; 7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bp = bpts; 7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < NBPTS; ++i, ++bp) { 7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0) 7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mread(bp->address, &bp->instr[0], 4) != 4) { 7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("Couldn't read instruction at %lx, " 7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "disabling breakpoint there\n", bp->address); 7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bp->enabled = 0; 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) { 7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("Breakpoint at %lx is on an mtmsrd or rfid " 7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "instruction, disabling it\n", bp->address); 7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bp->enabled = 0; 7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds store_inst(&bp->instr[0]); 7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bp->enabled & BP_IABR) 7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mwrite(bp->address, &bpinstr, 4) != 4) { 7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("Couldn't write instruction at %lx, " 7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "disabling breakpoint there\n", bp->address); 7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bp->enabled &= ~BP_TRAP; 7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds store_inst((void *)bp->address); 7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void insert_cpu_bpts(void) 7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7599422de3e953d0e60eb95f5430a9dd803eec1c6d7Michael Neuling struct arch_hw_breakpoint brk; 7609422de3e953d0e60eb95f5430a9dd803eec1c6d7Michael Neuling 7619422de3e953d0e60eb95f5430a9dd803eec1c6d7Michael Neuling if (dabr.enabled) { 7629422de3e953d0e60eb95f5430a9dd803eec1c6d7Michael Neuling brk.address = dabr.address; 7639422de3e953d0e60eb95f5430a9dd803eec1c6d7Michael Neuling brk.type = (dabr.enabled & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL; 7649422de3e953d0e60eb95f5430a9dd803eec1c6d7Michael Neuling brk.len = 8; 76521f585073d6347651f2262da187606fa1c4ee16dPaul Gortmaker __set_breakpoint(&brk); 7669422de3e953d0e60eb95f5430a9dd803eec1c6d7Michael Neuling } 7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (iabr && cpu_has_feature(CPU_FTR_IABR)) 768f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras mtspr(SPRN_IABR, iabr->address 7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds | (iabr->enabled & (BP_IABR|BP_IABR_TE))); 7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void remove_bpts(void) 7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct bpt *bp; 7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned instr; 7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bp = bpts; 7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < NBPTS; ++i, ++bp) { 7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP) 7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mread(bp->address, &instr, 4) == 4 7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds && instr == bpinstr 7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds && mwrite(bp->address, &bp->instr, 4) != 4) 7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("Couldn't remove breakpoint at %lx\n", 7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bp->address); 7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds store_inst((void *)bp->address); 7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void remove_cpu_bpts(void) 7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7949422de3e953d0e60eb95f5430a9dd803eec1c6d7Michael Neuling hw_breakpoint_disable(); 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cpu_has_feature(CPU_FTR_IABR)) 796f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras mtspr(SPRN_IABR, 0); 7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Command interpreting routine */ 8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char *last_cmd; 8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldscmds(struct pt_regs *excp) 8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int cmd = 0; 8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds last_cmd = NULL; 8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_regs = excp; 80926c8af5f01dfb91f709cc2ba07fb650949aae13eOlaf Hering 81026c8af5f01dfb91f709cc2ba07fb650949aae13eOlaf Hering if (!xmon_no_auto_backtrace) { 81126c8af5f01dfb91f709cc2ba07fb650949aae13eOlaf Hering xmon_no_auto_backtrace = 1; 81226c8af5f01dfb91f709cc2ba07fb650949aae13eOlaf Hering xmon_show_stack(excp->gpr[1], excp->link, excp->nip); 81326c8af5f01dfb91f709cc2ba07fb650949aae13eOlaf Hering } 81426c8af5f01dfb91f709cc2ba07fb650949aae13eOlaf Hering 8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(;;) { 8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_SMP 8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("%x:", smp_processor_id()); 8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* CONFIG_SMP */ 8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("mon> "); 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds flush_input(); 8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds termch = 0; 8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd = skipbl(); 8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( cmd == '\n' ) { 8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (last_cmd == NULL) 8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds take_input(last_cmd); 8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds last_cmd = NULL; 8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd = inchar(); 8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (cmd) { 8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'm': 8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd = inchar(); 8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (cmd) { 8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'm': 8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 's': 8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'd': 8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memops(cmd); 8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'l': 8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memlocate(); 8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'z': 8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memzcan(); 8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'i': 846b2b755b5f10eb32fbdc73a9907c07006b17f714bDavid Rientjes show_mem(0); 8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds termch = cmd; 8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memex(); 8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'd': 8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dump(); 8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'l': 8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds symbol_lookup(); 8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'r': 8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds prregs(excp); /* print regs */ 8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'e': 8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds excprint(excp); 8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'S': 8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds super_regs(); 8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 't': 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds backtrace(excp); 8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'f': 8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cacheflush(); 8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 's': 875ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman if (do_spu_cmd() == 0) 876ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman break; 8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (do_step(excp)) 8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return cmd; 8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'x': 8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'X': 882bb6b9b28d6847bc71f910e2e82c9040ff4b97ec0Benjamin Herrenschmidt return cmd; 8831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case EOF: 884bb6b9b28d6847bc71f910e2e82c9040ff4b97ec0Benjamin Herrenschmidt printf(" <no input ...>\n"); 885bb6b9b28d6847bc71f910e2e82c9040ff4b97ec0Benjamin Herrenschmidt mdelay(2000); 8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return cmd; 8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case '?': 8884d404edce30f911004850d472e05a31efd751662Ishizaki Kou xmon_puts(help_string); 8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'b': 8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bpt_cmds(); 8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'C': 8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds csum(); 8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'c': 8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cpu_cmd()) 8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'z': 9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bootcmds(); 9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 903f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras case 'p': 904f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras proccall(); 9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 906f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#ifdef CONFIG_PPC_STD_MMU 9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'u': 9081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dump_segments(); 9091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 91079873e8df64cc124cdcad56d1d8330b3f45690bcJimi Xenidis#elif defined(CONFIG_4xx) 9115a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt case 'u': 9125a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt dump_tlb_44x(); 9135a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt break; 91479873e8df64cc124cdcad56d1d8330b3f45690bcJimi Xenidis#elif defined(CONFIG_PPC_BOOK3E) 91503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt case 'u': 91603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt dump_tlb_book3e(); 91703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt break; 91803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt#endif 9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("Unrecognized command: "); 921e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman do { 9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (' ' < cmd && cmd <= '~') 9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds putchar(cmd); 9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("\\x%x", cmd); 9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd = inchar(); 927e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman } while (cmd != '\n'); 9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf(" (type ? for help)\n"); 9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 934cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer#ifdef CONFIG_BOOKE 935cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyerstatic int do_step(struct pt_regs *regs) 936cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer{ 937cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer regs->msr |= MSR_DE; 938cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM); 939cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer return 1; 940cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer} 941cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer#else 9421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 9431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Step a single instruction. 9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Some instructions we emulate, others we execute with MSR_SE set. 9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int do_step(struct pt_regs *regs) 9471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int instr; 9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int stepped; 9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check we are in 64-bit kernel mode, translation enabled */ 9529f0b079320ad1cc71ad7ea4e0ed0b64cd72bbd6dMichael Ellerman if ((regs->msr & (MSR_64BIT|MSR_PR|MSR_IR)) == (MSR_64BIT|MSR_IR)) { 9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mread(regs->nip, &instr, 4) == 4) { 9541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stepped = emulate_step(regs, instr); 9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (stepped < 0) { 9561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("Couldn't single-step %s instruction\n", 9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (IS_RFID(instr)? "rfid": "mtmsrd")); 9581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (stepped > 0) { 9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->trap = 0xd00 | (regs->trap & 1); 9621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("stepped to "); 9631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_print_symbol(regs->nip, " ", "\n"); 9641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ppc_inst_dump(regs->nip, 1, 0); 9651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 9661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->msr |= MSR_SE; 9701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 9711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 972cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer#endif 9731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void bootcmds(void) 9751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int cmd; 9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd = inchar(); 9791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cmd == 'r') 9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ppc_md.restart(NULL); 9811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (cmd == 'h') 9821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ppc_md.halt(); 9831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (cmd == 'p') 9841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ppc_md.power_off(); 9851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int cpu_cmd(void) 9881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_SMP 990fd3bb91287b600d8b389c159e8dd96391410087bPaul Mackerras unsigned long cpu, first_cpu, last_cpu; 9911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int timeout; 9921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!scanhex(&cpu)) { 9941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* print cpus waiting or in xmon */ 9951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("cpus stopped:"); 996fd3bb91287b600d8b389c159e8dd96391410087bPaul Mackerras last_cpu = first_cpu = NR_CPUS; 997bc1d7702910c7c7e88eb60b58429dbfe293683ceAnton Blanchard for_each_possible_cpu(cpu) { 998104699c0ab473535793b5fea156adaf309afd29bKOSAKI Motohiro if (cpumask_test_cpu(cpu, &cpus_in_xmon)) { 999fd3bb91287b600d8b389c159e8dd96391410087bPaul Mackerras if (cpu == last_cpu + 1) { 1000fd3bb91287b600d8b389c159e8dd96391410087bPaul Mackerras last_cpu = cpu; 1001fd3bb91287b600d8b389c159e8dd96391410087bPaul Mackerras } else { 1002fd3bb91287b600d8b389c159e8dd96391410087bPaul Mackerras if (last_cpu != first_cpu) 1003736256e4f1bc50bb8198c9b61dffd5fd0de17477Michael Ellerman printf("-0x%lx", last_cpu); 1004fd3bb91287b600d8b389c159e8dd96391410087bPaul Mackerras last_cpu = first_cpu = cpu; 1005736256e4f1bc50bb8198c9b61dffd5fd0de17477Michael Ellerman printf(" 0x%lx", cpu); 1006fd3bb91287b600d8b389c159e8dd96391410087bPaul Mackerras } 10071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1009fd3bb91287b600d8b389c159e8dd96391410087bPaul Mackerras if (last_cpu != first_cpu) 1010736256e4f1bc50bb8198c9b61dffd5fd0de17477Michael Ellerman printf("-0x%lx", last_cpu); 10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("\n"); 10121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 10131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* try to switch to cpu specified */ 1015104699c0ab473535793b5fea156adaf309afd29bKOSAKI Motohiro if (!cpumask_test_cpu(cpu, &cpus_in_xmon)) { 10161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("cpu 0x%x isn't in xmon\n", cpu); 10171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 10181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_taken = 0; 10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); 10211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_owner = cpu; 10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds timeout = 10000000; 10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (!xmon_taken) { 10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (--timeout == 0) { 10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_and_set_bit(0, &xmon_taken)) 10261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* take control back */ 10281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); 10291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_owner = smp_processor_id(); 1030736256e4f1bc50bb8198c9b61dffd5fd0de17477Michael Ellerman printf("cpu 0x%x didn't take control\n", cpu); 10311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 10321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds barrier(); 10341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 10361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 10371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 10381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* CONFIG_SMP */ 10391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned short fcstab[256] = { 10421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 10431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 10441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 10451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 10461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 10471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 10481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 10491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 10501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 10511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 10521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 10531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 10541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 10551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 10561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 10571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 10581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 10591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 10601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 10611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 10621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 10631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 10641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 10651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 10661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 10671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 10681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 10691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 10701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 10711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 10721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 10731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 10741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 10751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) 10771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 10791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldscsum(void) 10801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int i; 10821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned short fcs; 10831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char v; 10841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!scanhex(&adrs)) 10861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 10871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!scanhex(&ncsum)) 10881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 10891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcs = 0xffff; 10901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < ncsum; ++i) { 10911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mread(adrs+i, &v, 1) == 0) { 1092736256e4f1bc50bb8198c9b61dffd5fd0de17477Michael Ellerman printf("csum stopped at "REG"\n", adrs+i); 10931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcs = FCS(fcs, v); 10961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("%x\n", fcs); 10981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 11011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Check if this is a suitable place to put a breakpoint. 11021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 11031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic long check_bp_loc(unsigned long addr) 11041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int instr; 11061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds addr &= ~3; 110851fae6de24da57bc6cdaa1b253595c3513ecbf2dMichael Ellerman if (!is_kernel_addr(addr)) { 11091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("Breakpoints may only be placed at kernel addresses\n"); 11101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 11111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!mread(addr, &instr, sizeof(instr))) { 11131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("Can't read instruction at address %lx\n", addr); 11141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 11151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (IS_MTMSRD(instr) || IS_RFID(instr)) { 11171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("Breakpoints may not be placed on mtmsrd or rfid " 11181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "instructions\n"); 11191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 11201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 11221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1124e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellermanstatic char *breakpoint_help_string = 11251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "Breakpoint command usage:\n" 11261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "b show breakpoints\n" 11271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "b <addr> [cnt] set breakpoint at given instr addr\n" 11281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "bc clear all breakpoints\n" 11291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "bc <n/addr> clear breakpoint number n or at addr\n" 11301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n" 11311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "bd <addr> [cnt] set hardware data breakpoint\n" 11321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ""; 11331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 11351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsbpt_cmds(void) 11361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int cmd; 11381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long a; 11391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int mode, i; 11401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct bpt *bp; 11411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const char badaddr[] = "Only kernel addresses are permitted " 11421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "for breakpoints\n"; 11431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd = inchar(); 11451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (cmd) { 1146f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#ifndef CONFIG_8xx 11471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'd': /* bd - hardware data breakpoint */ 11481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode = 7; 11491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd = inchar(); 11501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cmd == 'r') 11511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode = 5; 11521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (cmd == 'w') 11531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode = 6; 11541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 11551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds termch = cmd; 11561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dabr.address = 0; 11571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dabr.enabled = 0; 11581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (scanhex(&dabr.address)) { 115951fae6de24da57bc6cdaa1b253595c3513ecbf2dMichael Ellerman if (!is_kernel_addr(dabr.address)) { 11601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf(badaddr); 11611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11639422de3e953d0e60eb95f5430a9dd803eec1c6d7Michael Neuling dabr.address &= ~HW_BRK_TYPE_DABR; 11641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dabr.enabled = mode | BP_DABR; 11651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'i': /* bi - hardware instr breakpoint */ 11691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!cpu_has_feature(CPU_FTR_IABR)) { 11701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("Hardware instruction breakpoint " 11711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "not supported on this cpu\n"); 11721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (iabr) { 11751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iabr->enabled &= ~(BP_IABR | BP_IABR_TE); 11761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iabr = NULL; 11771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!scanhex(&a)) 11791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!check_bp_loc(a)) 11811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bp = new_breakpoint(a); 11831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bp != NULL) { 11841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bp->enabled |= BP_IABR | BP_IABR_TE; 11851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iabr = bp; 11861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1188f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#endif 11891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'c': 11911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!scanhex(&a)) { 11921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* clear all breakpoints */ 11931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < NBPTS; ++i) 11941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bpts[i].enabled = 0; 11951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iabr = NULL; 11961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dabr.enabled = 0; 11971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("All breakpoints cleared\n"); 11981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (a <= NBPTS && a >= 1) { 12021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* assume a breakpoint number */ 12031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bp = &bpts[a-1]; /* bp nums are 1 based */ 12041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 12051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* assume a breakpoint address */ 12061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bp = at_breakpoint(a); 12079f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellerman if (bp == NULL) { 1208736256e4f1bc50bb8198c9b61dffd5fd0de17477Michael Ellerman printf("No breakpoint at %lx\n", a); 12091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1213736256e4f1bc50bb8198c9b61dffd5fd0de17477Michael Ellerman printf("Cleared breakpoint %lx (", BP_NUM(bp)); 12141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_print_symbol(bp->address, " ", ")\n"); 12151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bp->enabled = 0; 12161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 12191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds termch = cmd; 1220e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman cmd = skipbl(); 12211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cmd == '?') { 12221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf(breakpoint_help_string); 12231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds termch = cmd; 12261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!scanhex(&a)) { 12271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* print all breakpoints */ 12281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf(" type address\n"); 12291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dabr.enabled) { 1230f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras printf(" data "REG" [", dabr.address); 12311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dabr.enabled & 1) 12321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("r"); 12331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dabr.enabled & 2) 12341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("w"); 12351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("]\n"); 12361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (bp = bpts; bp < &bpts[NBPTS]; ++bp) { 12381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!bp->enabled) 12391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 12401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("%2x %s ", BP_NUM(bp), 12411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (bp->enabled & BP_IABR)? "inst": "trap"); 12421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_print_symbol(bp->address, " ", "\n"); 12431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!check_bp_loc(a)) 12481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bp = new_breakpoint(a); 12501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bp != NULL) 12511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bp->enabled |= BP_TRAP; 12521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Very cheap human name for vector lookup. */ 12571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic 12581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsconst char *getvecname(unsigned long vec) 12591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *ret; 12611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (vec) { 12631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x100: ret = "(System Reset)"; break; 12641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x200: ret = "(Machine Check)"; break; 12651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x300: ret = "(Data Access)"; break; 12661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x380: ret = "(Data SLB Access)"; break; 12671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x400: ret = "(Instruction Access)"; break; 12681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x480: ret = "(Instruction SLB Access)"; break; 12691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x500: ret = "(Hardware Interrupt)"; break; 12701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x600: ret = "(Alignment)"; break; 12711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x700: ret = "(Program Check)"; break; 12721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x800: ret = "(FPU Unavailable)"; break; 12731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x900: ret = "(Decrementer)"; break; 1274660e034ce167b0954b83fd024c8be02c2911dbc9Michael Ellerman case 0x980: ret = "(Hypervisor Decrementer)"; break; 1275660e034ce167b0954b83fd024c8be02c2911dbc9Michael Ellerman case 0xa00: ret = "(Doorbell)"; break; 12761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0xc00: ret = "(System Call)"; break; 12771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0xd00: ret = "(Single Step)"; break; 1278660e034ce167b0954b83fd024c8be02c2911dbc9Michael Ellerman case 0xe40: ret = "(Emulation Assist)"; break; 1279660e034ce167b0954b83fd024c8be02c2911dbc9Michael Ellerman case 0xe60: ret = "(HMI)"; break; 1280660e034ce167b0954b83fd024c8be02c2911dbc9Michael Ellerman case 0xe80: ret = "(Hypervisor Doorbell)"; break; 12811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0xf00: ret = "(Performance Monitor)"; break; 12821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0xf20: ret = "(Altivec Unavailable)"; break; 12831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x1300: ret = "(Instruction Breakpoint)"; break; 1284660e034ce167b0954b83fd024c8be02c2911dbc9Michael Ellerman case 0x1500: ret = "(Denormalisation)"; break; 1285660e034ce167b0954b83fd024c8be02c2911dbc9Michael Ellerman case 0x1700: ret = "(Altivec Assist)"; break; 12861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: ret = ""; 12871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 12891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void get_function_bounds(unsigned long pc, unsigned long *startp, 12921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long *endp) 12931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long size, offset; 12951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const char *name; 12961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *startp = *endp = 0; 12981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pc == 0) 12991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 13001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (setjmp(bus_error_jmp) == 0) { 13011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds catch_memory_errors = 1; 13021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync(); 1303ffb45122766db220d0bf3d01848d575fbbcb6430Alexey Dobriyan name = kallsyms_lookup(pc, &size, &offset, NULL, tmpstr); 13041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (name != NULL) { 13051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *startp = pc - offset; 13061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *endp = pc - offset + size; 13071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync(); 13091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds catch_memory_errors = 0; 13111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1313ec2b36b9f23cfbbe94d89724b796b44fd57d5221Benjamin Herrenschmidt#define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long)) 1314ec2b36b9f23cfbbe94d89724b796b44fd57d5221Benjamin Herrenschmidt#define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long)) 1315ec2b36b9f23cfbbe94d89724b796b44fd57d5221Benjamin Herrenschmidt 13161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void xmon_show_stack(unsigned long sp, unsigned long lr, 13171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long pc) 13181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13190104cd6839bd575f0aa1af4125eb865dc0391aaeMichael Ellerman int max_to_print = 64; 13201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long ip; 13211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long newsp; 13221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long marker; 13231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pt_regs regs; 13241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13250104cd6839bd575f0aa1af4125eb865dc0391aaeMichael Ellerman while (max_to_print--) { 13261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sp < PAGE_OFFSET) { 13271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sp != 0) 13281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("SP (%lx) is in userspace\n", sp); 13291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1332f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long)) 13331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds || !mread(sp, &newsp, sizeof(unsigned long))) { 13341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("Couldn't read stack frame at %lx\n", sp); 13351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 13391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * For the first stack frame, try to work out if 13401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * LR and/or the saved LR value in the bottommost 13411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * stack frame are valid. 13421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 13431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((pc | lr) != 0) { 13441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long fnstart, fnend; 13451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long nextip; 13461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int printip = 1; 13471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds get_function_bounds(pc, &fnstart, &fnend); 13491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nextip = 0; 13501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (newsp > sp) 1351f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras mread(newsp + LRSAVE_OFFSET, &nextip, 13521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sizeof(unsigned long)); 13531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (lr == ip) { 13541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (lr < PAGE_OFFSET 13551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds || (fnstart <= lr && lr < fnend)) 13561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printip = 0; 13571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (lr == nextip) { 13581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printip = 0; 13591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (lr >= PAGE_OFFSET 13601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds && !(fnstart <= lr && lr < fnend)) { 13611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("[link register ] "); 13621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_print_symbol(lr, " ", "\n"); 13631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (printip) { 1365f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras printf("["REG"] ", sp); 13661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_print_symbol(ip, " ", " (unreliable)\n"); 13671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pc = lr = 0; 13691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 1371f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras printf("["REG"] ", sp); 13721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_print_symbol(ip, " ", "\n"); 13731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Look for "regshere" marker to see if this is 13761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds an exception frame. */ 1377f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long)) 1378ec2b36b9f23cfbbe94d89724b796b44fd57d5221Benjamin Herrenschmidt && marker == STACK_FRAME_REGS_MARKER) { 1379c4de38093ed9fe94fa35c3adb14afc40bf05e1daMichael Ellerman if (mread(sp + STACK_FRAME_OVERHEAD, ®s, sizeof(regs)) 13801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds != sizeof(regs)) { 13811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("Couldn't read registers at %lx\n", 1382c4de38093ed9fe94fa35c3adb14afc40bf05e1daMichael Ellerman sp + STACK_FRAME_OVERHEAD); 13831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1385e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman printf("--- Exception: %lx %s at ", regs.trap, 13861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds getvecname(TRAP(®s))); 13871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pc = regs.nip; 13881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lr = regs.link; 13891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_print_symbol(pc, " ", "\n"); 13901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (newsp == 0) 13931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sp = newsp; 13960104cd6839bd575f0aa1af4125eb865dc0391aaeMichael Ellerman } 13971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void backtrace(struct pt_regs *excp) 14001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long sp; 14021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (scanhex(&sp)) 14041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_show_stack(sp, 0, 0); 14051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 14061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_show_stack(excp->gpr[1], excp->link, excp->nip); 14071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scannl(); 14081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void print_bug_trap(struct pt_regs *regs) 14111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1412ebdba9af940d63e469dc8e46b4aa1fc474e8ee2dPaul Mackerras#ifdef CONFIG_BUG 141373c9ceab40b1269d6195e556773167c078ac8311Jeremy Fitzhardinge const struct bug_entry *bug; 14141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long addr; 14151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (regs->msr & MSR_PR) 14171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; /* not in kernel */ 14181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds addr = regs->nip; /* address of trap instruction */ 14191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (addr < PAGE_OFFSET) 14201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 14211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bug = find_bug(regs->nip); 14221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bug == NULL) 14231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 142473c9ceab40b1269d6195e556773167c078ac8311Jeremy Fitzhardinge if (is_warning_bug(bug)) 14251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 14261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14270a7c7efccc08f00ae6fc8e1f2de0ee61f07357fdStephen Rothwell#ifdef CONFIG_DEBUG_BUGVERBOSE 142873c9ceab40b1269d6195e556773167c078ac8311Jeremy Fitzhardinge printf("kernel BUG at %s:%u!\n", 142973c9ceab40b1269d6195e556773167c078ac8311Jeremy Fitzhardinge bug->file, bug->line); 14300a7c7efccc08f00ae6fc8e1f2de0ee61f07357fdStephen Rothwell#else 14310a7c7efccc08f00ae6fc8e1f2de0ee61f07357fdStephen Rothwell printf("kernel BUG at %p!\n", (void *)bug->bug_addr); 14320a7c7efccc08f00ae6fc8e1f2de0ee61f07357fdStephen Rothwell#endif 1433ebdba9af940d63e469dc8e46b4aa1fc474e8ee2dPaul Mackerras#endif /* CONFIG_BUG */ 14341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14369f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void excprint(struct pt_regs *fp) 14371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long trap; 14391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_SMP 14411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("cpu 0x%x: ", smp_processor_id()); 14421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* CONFIG_SMP */ 14431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds trap = TRAP(fp); 14451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp); 14461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf(" pc: "); 14471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_print_symbol(fp->nip, ": ", "\n"); 14481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf(" lr: ", fp->link); 14501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_print_symbol(fp->link, ": ", "\n"); 14511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf(" sp: %lx\n", fp->gpr[1]); 14531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf(" msr: %lx\n", fp->msr); 14541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1455ce54152f429ed5e6ad83e5e9f61825b5a795dd1eAneesh Kumar K.V if (trap == 0x300 || trap == 0x380 || trap == 0x600 || trap == 0x200) { 14561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf(" dar: %lx\n", fp->dar); 14571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (trap != 0x380) 14581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf(" dsisr: %lx\n", fp->dsisr); 14591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf(" current = 0x%lx\n", current); 1462f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#ifdef CONFIG_PPC64 14637230c5644188cd9e3fb380cc97dde00c464a3ba7Benjamin Herrenschmidt printf(" paca = 0x%lx\t softe: %d\t irq_happened: 0x%02x\n", 14647230c5644188cd9e3fb380cc97dde00c464a3ba7Benjamin Herrenschmidt local_paca, local_paca->soft_enabled, local_paca->irq_happened); 1465f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#endif 14661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (current) { 14671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf(" pid = %ld, comm = %s\n", 14681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds current->pid, current->comm); 14691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (trap == 0x700) 14721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds print_bug_trap(fp); 14731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14759f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void prregs(struct pt_regs *fp) 14761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1477f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras int n, trap; 14781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long base; 14791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pt_regs regs; 14801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (scanhex(&base)) { 14821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (setjmp(bus_error_jmp) == 0) { 14831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds catch_memory_errors = 1; 14841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync(); 14851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs = *(struct pt_regs *)base; 14861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync(); 14871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __delay(200); 14881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 14891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds catch_memory_errors = 0; 1490f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras printf("*** Error reading registers from "REG"\n", 14911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds base); 14921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 14931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds catch_memory_errors = 0; 14951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fp = ®s; 14961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1498f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#ifdef CONFIG_PPC64 14991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (FULL_REGS(fp)) { 15001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (n = 0; n < 16; ++n) 1501f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras printf("R%.2ld = "REG" R%.2ld = "REG"\n", 15021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n, fp->gpr[n], n+16, fp->gpr[n+16]); 15031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 15041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (n = 0; n < 7; ++n) 1505f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras printf("R%.2ld = "REG" R%.2ld = "REG"\n", 15061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n, fp->gpr[n], n+7, fp->gpr[n+7]); 15071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1508f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#else 1509f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras for (n = 0; n < 32; ++n) { 1510f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras printf("R%.2d = %.8x%s", n, fp->gpr[n], 1511f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras (n & 3) == 3? "\n": " "); 1512f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras if (n == 12 && !FULL_REGS(fp)) { 1513f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras printf("\n"); 1514f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras break; 1515f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras } 1516f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras } 1517f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#endif 15181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("pc = "); 15191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_print_symbol(fp->nip, " ", "\n"); 152048404f2e95ef0ffd8134d89c8abcd1a15e15f1b0Paul Mackerras if (TRAP(fp) != 0xc00 && cpu_has_feature(CPU_FTR_CFAR)) { 152148404f2e95ef0ffd8134d89c8abcd1a15e15f1b0Paul Mackerras printf("cfar= "); 152248404f2e95ef0ffd8134d89c8abcd1a15e15f1b0Paul Mackerras xmon_print_symbol(fp->orig_gpr3, " ", "\n"); 152348404f2e95ef0ffd8134d89c8abcd1a15e15f1b0Paul Mackerras } 15241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("lr = "); 15251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_print_symbol(fp->link, " ", "\n"); 1526f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr); 1527f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras printf("ctr = "REG" xer = "REG" trap = %4lx\n", 15281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fp->ctr, fp->xer, fp->trap); 1529f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras trap = TRAP(fp); 1530f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras if (trap == 0x300 || trap == 0x380 || trap == 0x600) 1531f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr); 15321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15349f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void cacheflush(void) 15351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int cmd; 15371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long nflush; 15381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd = inchar(); 15401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cmd != 'i') 15411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds termch = cmd; 15421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scanhex((void *)&adrs); 15431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (termch != '\n') 15441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds termch = 0; 15451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nflush = 1; 15461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scanhex(&nflush); 15471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES; 15481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (setjmp(bus_error_jmp) == 0) { 15491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds catch_memory_errors = 1; 15501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync(); 15511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cmd != 'i') { 15531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES) 15541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cflush((void *) adrs); 15551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 15561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES) 15571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cinval((void *) adrs); 15581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync(); 15601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* wait a little while to see if we get a machine check */ 15611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __delay(200); 15621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds catch_memory_errors = 0; 15641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15669f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic unsigned long 15671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsread_spr(int n) 15681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int instrs[2]; 15701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long (*code)(void); 15711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long ret = -1UL; 1572548ccebc2a79c780724529948c79de0613f96776Paul Mackerras#ifdef CONFIG_PPC64 1573548ccebc2a79c780724529948c79de0613f96776Paul Mackerras unsigned long opd[3]; 15741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds opd[0] = (unsigned long)instrs; 15761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds opd[1] = 0; 15771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds opd[2] = 0; 1578548ccebc2a79c780724529948c79de0613f96776Paul Mackerras code = (unsigned long (*)(void)) opd; 1579548ccebc2a79c780724529948c79de0613f96776Paul Mackerras#else 1580548ccebc2a79c780724529948c79de0613f96776Paul Mackerras code = (unsigned long (*)(void)) instrs; 1581548ccebc2a79c780724529948c79de0613f96776Paul Mackerras#endif 1582548ccebc2a79c780724529948c79de0613f96776Paul Mackerras 1583548ccebc2a79c780724529948c79de0613f96776Paul Mackerras /* mfspr r3,n; blr */ 1584548ccebc2a79c780724529948c79de0613f96776Paul Mackerras instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6); 1585548ccebc2a79c780724529948c79de0613f96776Paul Mackerras instrs[1] = 0x4e800020; 15861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds store_inst(instrs); 15871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds store_inst(instrs+1); 15881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (setjmp(bus_error_jmp) == 0) { 15901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds catch_memory_errors = 1; 15911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync(); 15921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = code(); 15941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync(); 15961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* wait a little while to see if we get a machine check */ 15971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __delay(200); 15981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = size; 15991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 16021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 16031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16049f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void 16051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldswrite_spr(int n, unsigned long val) 16061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 16071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int instrs[2]; 16081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long (*code)(unsigned long); 1609548ccebc2a79c780724529948c79de0613f96776Paul Mackerras#ifdef CONFIG_PPC64 16101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long opd[3]; 16111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds opd[0] = (unsigned long)instrs; 16131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds opd[1] = 0; 16141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds opd[2] = 0; 1615548ccebc2a79c780724529948c79de0613f96776Paul Mackerras code = (unsigned long (*)(unsigned long)) opd; 1616548ccebc2a79c780724529948c79de0613f96776Paul Mackerras#else 1617548ccebc2a79c780724529948c79de0613f96776Paul Mackerras code = (unsigned long (*)(unsigned long)) instrs; 1618548ccebc2a79c780724529948c79de0613f96776Paul Mackerras#endif 1619548ccebc2a79c780724529948c79de0613f96776Paul Mackerras 1620548ccebc2a79c780724529948c79de0613f96776Paul Mackerras instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6); 1621548ccebc2a79c780724529948c79de0613f96776Paul Mackerras instrs[1] = 0x4e800020; 16221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds store_inst(instrs); 16231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds store_inst(instrs+1); 16241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (setjmp(bus_error_jmp) == 0) { 16261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds catch_memory_errors = 1; 16271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync(); 16281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds code(val); 16301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync(); 16321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* wait a little while to see if we get a machine check */ 16331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __delay(200); 16341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = size; 16351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 16371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long regno; 16391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern char exc_prolog; 16401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern char dec_exc; 16411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16429f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void super_regs(void) 16431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 16441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int cmd; 16451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long val; 16461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd = skipbl(); 16481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cmd == '\n') { 1649e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman unsigned long sp, toc; 16501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds asm("mr %0,1" : "=r" (sp) :); 16511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds asm("mr %0,2" : "=r" (toc) :); 16521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1653f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras printf("msr = "REG" sprg0= "REG"\n", 1654f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras mfmsr(), mfspr(SPRN_SPRG0)); 1655f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras printf("pvr = "REG" sprg1= "REG"\n", 1656e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman mfspr(SPRN_PVR), mfspr(SPRN_SPRG1)); 1657f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras printf("dec = "REG" sprg2= "REG"\n", 1658f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras mfspr(SPRN_DEC), mfspr(SPRN_SPRG2)); 1659f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3)); 1660f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR)); 16611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 16631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scanhex(®no); 16661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (cmd) { 16671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'w': 16681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = read_spr(regno); 16691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scanhex(&val); 16701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_spr(regno, val); 16711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* fall through */ 16721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'r': 16731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("spr %lx = %lx\n", regno, read_spr(regno)); 16741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 16751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scannl(); 16771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 16781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 16801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Stuff for reading and writing memory safely 16811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 16829f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic int 16831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmread(unsigned long adrs, void *buf, int size) 16841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 16851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds volatile int n; 16861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *p, *q; 16871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = 0; 16891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (setjmp(bus_error_jmp) == 0) { 16901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds catch_memory_errors = 1; 16911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync(); 16921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p = (char *)adrs; 16931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds q = (char *)buf; 16941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (size) { 16951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 2: 1696f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras *(u16 *)q = *(u16 *)p; 16971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 16981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 4: 1699f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras *(u32 *)q = *(u32 *)p; 17001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 17011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 8: 1702f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras *(u64 *)q = *(u64 *)p; 17031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 17041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 17051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for( ; n < size; ++n) { 17061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *q++ = *p++; 17071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync(); 17081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync(); 17111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* wait a little while to see if we get a machine check */ 17121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __delay(200); 17131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = size; 17141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds catch_memory_errors = 0; 17161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return n; 17171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 17181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17199f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic int 17201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmwrite(unsigned long adrs, void *buf, int size) 17211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 17221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds volatile int n; 17231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *p, *q; 17241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = 0; 17261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (setjmp(bus_error_jmp) == 0) { 17271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds catch_memory_errors = 1; 17281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync(); 17291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p = (char *) adrs; 17301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds q = (char *) buf; 17311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (size) { 17321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 2: 1733f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras *(u16 *)p = *(u16 *)q; 17341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 17351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 4: 1736f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras *(u32 *)p = *(u32 *)q; 17371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 17381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 8: 1739f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras *(u64 *)p = *(u64 *)q; 17401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 17411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 17421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for ( ; n < size; ++n) { 17431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *p++ = *q++; 17441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync(); 17451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync(); 17481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* wait a little while to see if we get a machine check */ 17491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __delay(200); 17501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = size; 17511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 1752736256e4f1bc50bb8198c9b61dffd5fd0de17477Michael Ellerman printf("*** Error writing address "REG"\n", adrs + n); 17531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds catch_memory_errors = 0; 17551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return n; 17561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 17571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int fault_type; 1759f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerrasstatic int fault_except; 17601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char *fault_chars[] = { "--", "**", "##" }; 17611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1762f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerrasstatic int handle_fault(struct pt_regs *regs) 17631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1764f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras fault_except = TRAP(regs); 17651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (TRAP(regs)) { 17661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x200: 17671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fault_type = 0; 17681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 17691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x300: 17701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x380: 17711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fault_type = 1; 17721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 17731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 17741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fault_type = 2; 17751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds longjmp(bus_error_jmp, 1); 17781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 17801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 17811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t)) 17831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17849f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void 17851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsbyterev(unsigned char *val, int size) 17861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 17871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int t; 17881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (size) { 17901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 2: 17911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SWAP(val[0], val[1], t); 17921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 17931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 4: 17941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SWAP(val[0], val[3], t); 17951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SWAP(val[1], val[2], t); 17961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 17971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 8: /* is there really any use for this? */ 17981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SWAP(val[0], val[7], t); 17991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SWAP(val[1], val[6], t); 18001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SWAP(val[2], val[5], t); 18011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SWAP(val[3], val[4], t); 18021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 18031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 18041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 18051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int brev; 18071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int mnoread; 18081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1809e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellermanstatic char *memex_help_string = 18101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "Memory examine command usage:\n" 18111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "m [addr] [flags] examine/change memory\n" 18121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " addr is optional. will start where left off.\n" 18131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " flags may include chars from this set:\n" 18141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " b modify by bytes (default)\n" 18151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " w modify by words (2 byte)\n" 18161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " l modify by longs (4 byte)\n" 18171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " d modify by doubleword (8 byte)\n" 18181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " r toggle reverse byte order mode\n" 18191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " n do not read memory (for i/o spaces)\n" 18201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " . ok to read (default)\n" 18211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "NOTE: flags are saved as defaults\n" 18221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ""; 18231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1824e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellermanstatic char *memex_subcmd_help_string = 18251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "Memory examine subcommands:\n" 18261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " hexval write this val to current location\n" 18271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " 'string' write chars from string to this location\n" 18281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " ' increment address\n" 18291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " ^ decrement address\n" 18301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n" 18311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n" 18321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " ` clear no-read flag\n" 18331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " ; stay at this addr\n" 18341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " v change to byte mode\n" 18351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " w change to word (2 byte) mode\n" 18361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " l change to long (4 byte) mode\n" 18371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " u change to doubleword (8 byte) mode\n" 18381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " m addr change current addr\n" 18391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " n toggle no-read flag\n" 18401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " r toggle byte reverse flag\n" 18411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " < count back up count bytes\n" 18421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " > count skip forward count bytes\n" 18431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " x exit this mode\n" 18441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ""; 18451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18469f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void 18471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmemex(void) 18481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 18491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int cmd, inc, i, nslash; 18501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long n; 18511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char val[16]; 18521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scanhex((void *)&adrs); 18541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd = skipbl(); 18551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cmd == '?') { 18561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf(memex_help_string); 18571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 18581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 18591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds termch = cmd; 18601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 18611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds last_cmd = "m\n"; 18621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while ((cmd = skipbl()) != '\n') { 18631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch( cmd ){ 18641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'b': size = 1; break; 18651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'w': size = 2; break; 18661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'l': size = 4; break; 18671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'd': size = 8; break; 18681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'r': brev = !brev; break; 18691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'n': mnoread = 1; break; 18701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case '.': mnoread = 0; break; 18711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 18721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 18731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( size <= 0 ) 18741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = 1; 18751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if( size > 8 ) 18761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = 8; 18771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(;;){ 18781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!mnoread) 18791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = mread(adrs, val, size); 1880e1449ed956ae29129bde3e5137dde1d579d585ffPaul Mackerras printf(REG"%c", adrs, brev? 'r': ' '); 18811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!mnoread) { 18821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (brev) 18831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds byterev(val, size); 18841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds putchar(' '); 18851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < n; ++i) 18861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("%.2x", val[i]); 18871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (; i < size; ++i) 18881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("%s", fault_chars[fault_type]); 18891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 18901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds putchar(' '); 18911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds inc = size; 18921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nslash = 0; 18931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(;;){ 18941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( scanhex(&n) ){ 18951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < size; ++i) 18961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val[i] = n >> (i * 8); 18971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!brev) 18981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds byterev(val, size); 18991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mwrite(adrs, val, size); 19001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds inc = size; 19011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 19021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd = skipbl(); 19031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cmd == '\n') 19041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 19051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds inc = 0; 19061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (cmd) { 19071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case '\'': 19081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(;;){ 19091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = inchar(); 19101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( n == '\\' ) 19111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = bsesc(); 19121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if( n == '\'' ) 19131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 19141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < size; ++i) 19151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val[i] = n >> (i * 8); 19161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!brev) 19171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds byterev(val, size); 19181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mwrite(adrs, val, size); 19191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adrs += size; 19201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 19211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adrs -= size; 19221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds inc = size; 19231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 19241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ',': 19251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adrs += size; 19261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 19271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case '.': 19281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mnoread = 0; 19291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 19301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ';': 19311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 19321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'x': 19331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case EOF: 19341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scannl(); 19351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 19361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'b': 19371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'v': 19381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = 1; 19391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 19401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'w': 19411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = 2; 19421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 19431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'l': 19441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = 4; 19451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 19461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'u': 19471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = 8; 19481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 19491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case '^': 19501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adrs -= size; 19511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 19521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 19531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case '/': 19541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nslash > 0) 19551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adrs -= 1 << nslash; 19561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 19571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nslash = 0; 19581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nslash += 4; 19591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adrs += 1 << nslash; 19601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 19611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case '\\': 19621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nslash < 0) 19631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adrs += 1 << -nslash; 19641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 19651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nslash = 0; 19661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nslash -= 4; 19671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adrs -= 1 << -nslash; 19681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 19691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'm': 19701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scanhex((void *)&adrs); 19711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 19721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'n': 19731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mnoread = 1; 19741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 19751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'r': 19761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds brev = !brev; 19771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 19781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case '<': 19791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = size; 19801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scanhex(&n); 19811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adrs -= n; 19821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 19831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case '>': 19841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = size; 19851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scanhex(&n); 19861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adrs += n; 19871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 19881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case '?': 19891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf(memex_subcmd_help_string); 19901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 19911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 19921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 19931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adrs += inc; 19941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 19951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 19961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19979f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic int 19981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsbsesc(void) 19991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 20001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int c; 20011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = inchar(); 20031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch( c ){ 20041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'n': c = '\n'; break; 20051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'r': c = '\r'; break; 20061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'b': c = '\b'; break; 20071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 't': c = '\t'; break; 20081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 20091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return c; 20101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 20111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20127e5b59384eebe35bff8429243f089931ce1cdf38Olaf Heringstatic void xmon_rawdump (unsigned long adrs, long ndump) 20137e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering{ 20147e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering long n, m, r, nr; 20157e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering unsigned char temp[16]; 20167e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering 20177e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering for (n = ndump; n > 0;) { 20187e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering r = n < 16? n: 16; 20197e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering nr = mread(adrs, temp, r); 20207e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering adrs += nr; 20217e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering for (m = 0; m < r; ++m) { 20227e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering if (m < nr) 20237e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering printf("%.2x", temp[m]); 20247e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering else 20257e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering printf("%s", fault_chars[fault_type]); 20267e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering } 20277e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering n -= r; 20287e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering if (nr < r) 20297e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering break; 20307e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering } 20317e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering printf("\n"); 20327e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering} 20337e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering 2034ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman#ifdef CONFIG_PPC64 2035ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellermanstatic void dump_one_paca(int cpu) 2036ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman{ 2037ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman struct paca_struct *p; 2038ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman 2039ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman if (setjmp(bus_error_jmp) != 0) { 2040ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman printf("*** Error dumping paca for cpu 0x%x!\n", cpu); 2041ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman return; 2042ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman } 2043ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman 2044ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman catch_memory_errors = 1; 2045ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman sync(); 2046ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman 2047ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman p = &paca[cpu]; 2048ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman 2049ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman printf("paca for cpu 0x%x @ %p:\n", cpu, p); 2050ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman 2051ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman printf(" %-*s = %s\n", 16, "possible", cpu_possible(cpu) ? "yes" : "no"); 2052ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman printf(" %-*s = %s\n", 16, "present", cpu_present(cpu) ? "yes" : "no"); 2053ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman printf(" %-*s = %s\n", 16, "online", cpu_online(cpu) ? "yes" : "no"); 2054ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman 2055ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman#define DUMP(paca, name, format) \ 2056ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman printf(" %-*s = %#-*"format"\t(0x%lx)\n", 16, #name, 18, paca->name, \ 2057ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman offsetof(struct paca_struct, name)); 2058ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman 2059ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman DUMP(p, lock_token, "x"); 2060ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman DUMP(p, paca_index, "x"); 2061ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman DUMP(p, kernel_toc, "lx"); 2062ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman DUMP(p, kernelbase, "lx"); 2063ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman DUMP(p, kernel_msr, "lx"); 2064ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman DUMP(p, emergency_sp, "p"); 2065729b0f715371ce1e7636b4958fc45d6882442456Mahesh Salgaonkar#ifdef CONFIG_PPC_BOOK3S_64 2066729b0f715371ce1e7636b4958fc45d6882442456Mahesh Salgaonkar DUMP(p, mc_emergency_sp, "p"); 2067729b0f715371ce1e7636b4958fc45d6882442456Mahesh Salgaonkar DUMP(p, in_mce, "x"); 2068729b0f715371ce1e7636b4958fc45d6882442456Mahesh Salgaonkar#endif 2069ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman DUMP(p, data_offset, "lx"); 2070ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman DUMP(p, hw_cpu_id, "x"); 2071ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman DUMP(p, cpu_start, "x"); 2072ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman DUMP(p, kexec_state, "x"); 2073ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman DUMP(p, __current, "p"); 2074ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman DUMP(p, kstack, "lx"); 2075ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman DUMP(p, stab_rr, "lx"); 2076ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman DUMP(p, saved_r1, "lx"); 2077ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman DUMP(p, trap_save, "x"); 2078ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman DUMP(p, soft_enabled, "x"); 2079ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman DUMP(p, irq_happened, "x"); 2080ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman DUMP(p, io_sync, "x"); 2081ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman DUMP(p, irq_work_pending, "x"); 2082ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman DUMP(p, nap_state_lost, "x"); 2083ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman 2084ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman#undef DUMP 2085ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman 2086ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman catch_memory_errors = 0; 2087ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman sync(); 2088ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman} 2089ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman 2090ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellermanstatic void dump_all_pacas(void) 2091ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman{ 2092ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman int cpu; 2093ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman 2094ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman if (num_possible_cpus() == 0) { 2095ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman printf("No possible cpus, use 'dp #' to dump individual cpus\n"); 2096ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman return; 2097ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman } 2098ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman 2099ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman for_each_possible_cpu(cpu) 2100ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman dump_one_paca(cpu); 2101ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman} 2102ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman 2103ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellermanstatic void dump_pacas(void) 2104ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman{ 2105ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman unsigned long num; 2106ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman int c; 2107ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman 2108ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman c = inchar(); 2109ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman if (c == 'a') { 2110ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman dump_all_pacas(); 2111ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman return; 2112ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman } 2113ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman 2114ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman termch = c; /* Put c back, it wasn't 'a' */ 2115ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman 2116ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman if (scanhex(&num)) 2117ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman dump_one_paca(num); 2118ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman else 2119ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman dump_one_paca(xmon_owner); 2120ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman} 2121ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman#endif 2122ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman 21231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define isxdigit(c) (('0' <= (c) && (c) <= '9') \ 21241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds || ('a' <= (c) && (c) <= 'f') \ 21251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds || ('A' <= (c) && (c) <= 'F')) 21269f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void 21271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsdump(void) 21281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 21291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int c; 21301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = inchar(); 2132ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman 2133ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman#ifdef CONFIG_PPC64 2134ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman if (c == 'p') { 2135ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman dump_pacas(); 2136ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman return; 2137ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman } 2138ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman#endif 2139ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman 21401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n') 21411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds termch = c; 21421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scanhex((void *)&adrs); 21431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (termch != '\n') 21441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds termch = 0; 21451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c == 'i') { 21461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scanhex(&nidump); 21471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nidump == 0) 21481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nidump = 16; 21491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (nidump > MAX_DUMP) 21501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nidump = MAX_DUMP; 21511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adrs += ppc_inst_dump(adrs, nidump, 1); 21521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds last_cmd = "di\n"; 2153f312deb4cd0c88196edf6dab192b7d42514398d6Vinay Sridhar } else if (c == 'l') { 2154f312deb4cd0c88196edf6dab192b7d42514398d6Vinay Sridhar dump_log_buf(); 21557e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering } else if (c == 'r') { 21567e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering scanhex(&ndump); 21577e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering if (ndump == 0) 21587e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering ndump = 64; 21597e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering xmon_rawdump(adrs, ndump); 21607e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering adrs += ndump; 21617e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering last_cmd = "dr\n"; 21621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 21631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scanhex(&ndump); 21641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ndump == 0) 21651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ndump = 64; 21661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (ndump > MAX_DUMP) 21671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ndump = MAX_DUMP; 21681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds prdump(adrs, ndump); 21691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adrs += ndump; 21701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds last_cmd = "d\n"; 21711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 21721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 21731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21749f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void 21751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsprdump(unsigned long adrs, long ndump) 21761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 21771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds long n, m, c, r, nr; 21781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char temp[16]; 21791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (n = ndump; n > 0;) { 2181f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras printf(REG, adrs); 21821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds putchar(' '); 21831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r = n < 16? n: 16; 21841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nr = mread(adrs, temp, r); 21851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adrs += nr; 21861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (m = 0; m < r; ++m) { 2187e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman if ((m & (sizeof(long) - 1)) == 0 && m > 0) 2188e1449ed956ae29129bde3e5137dde1d579d585ffPaul Mackerras putchar(' '); 21891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (m < nr) 21901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("%.2x", temp[m]); 21911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 21921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("%s", fault_chars[fault_type]); 21931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2194e1449ed956ae29129bde3e5137dde1d579d585ffPaul Mackerras for (; m < 16; ++m) { 2195e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman if ((m & (sizeof(long) - 1)) == 0) 2196e1449ed956ae29129bde3e5137dde1d579d585ffPaul Mackerras putchar(' '); 21971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf(" "); 2198e1449ed956ae29129bde3e5137dde1d579d585ffPaul Mackerras } 21991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf(" |"); 22001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (m = 0; m < r; ++m) { 22011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (m < nr) { 22021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = temp[m]; 22031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds putchar(' ' <= c && c <= '~'? c: '.'); 22041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 22051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds putchar(' '); 22061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 22071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n -= r; 22081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (; m < 16; ++m) 22091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds putchar(' '); 22101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("|\n"); 22111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nr < r) 22121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 22131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 22141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 22151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22164c4c8723684b1b2cd0dfdf5e0685f35642bde253Michael Ellermantypedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr); 22174c4c8723684b1b2cd0dfdf5e0685f35642bde253Michael Ellerman 22189f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic int 22194c4c8723684b1b2cd0dfdf5e0685f35642bde253Michael Ellermangeneric_inst_dump(unsigned long adr, long count, int praddr, 22204c4c8723684b1b2cd0dfdf5e0685f35642bde253Michael Ellerman instruction_dump_func dump_func) 22211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 22221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int nr, dotted; 22231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long first_adr; 22241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long inst, last_inst = 0; 22251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char val[4]; 22261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dotted = 0; 22281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (first_adr = adr; count > 0; --count, adr += 4) { 22291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nr = mread(adr, val, 4); 22301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nr == 0) { 22311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (praddr) { 22321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const char *x = fault_chars[fault_type]; 2233f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras printf(REG" %s%s%s%s\n", adr, x, x, x, x); 22341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 22351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 22361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 22371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds inst = GETWORD(val); 22381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (adr > first_adr && inst == last_inst) { 22391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dotted) { 22401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf(" ...\n"); 22411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dotted = 1; 22421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 22431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 22441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 22451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dotted = 0; 22461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds last_inst = inst; 22471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (praddr) 2248f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras printf(REG" %.8x", adr, inst); 22491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("\t"); 22504c4c8723684b1b2cd0dfdf5e0685f35642bde253Michael Ellerman dump_func(inst, adr); 22511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("\n"); 22521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 22531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return adr - first_adr; 22541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 22551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22569f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic int 22574c4c8723684b1b2cd0dfdf5e0685f35642bde253Michael Ellermanppc_inst_dump(unsigned long adr, long count, int praddr) 22584c4c8723684b1b2cd0dfdf5e0685f35642bde253Michael Ellerman{ 22594c4c8723684b1b2cd0dfdf5e0685f35642bde253Michael Ellerman return generic_inst_dump(adr, count, praddr, print_insn_powerpc); 22604c4c8723684b1b2cd0dfdf5e0685f35642bde253Michael Ellerman} 22614c4c8723684b1b2cd0dfdf5e0685f35642bde253Michael Ellerman 22621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid 22631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsprint_address(unsigned long addr) 22641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 22651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_print_symbol(addr, "\t# ", ""); 22661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 22671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2268f312deb4cd0c88196edf6dab192b7d42514398d6Vinay Sridharvoid 2269f312deb4cd0c88196edf6dab192b7d42514398d6Vinay Sridhardump_log_buf(void) 2270f312deb4cd0c88196edf6dab192b7d42514398d6Vinay Sridhar{ 2271ca5dd3954a62dc14c2afff1c34b3b5d8dc74f777Michael Ellerman struct kmsg_dumper dumper = { .active = 1 }; 2272ca5dd3954a62dc14c2afff1c34b3b5d8dc74f777Michael Ellerman unsigned char buf[128]; 2273ca5dd3954a62dc14c2afff1c34b3b5d8dc74f777Michael Ellerman size_t len; 2274f312deb4cd0c88196edf6dab192b7d42514398d6Vinay Sridhar 2275e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman if (setjmp(bus_error_jmp) != 0) { 2276ca5dd3954a62dc14c2afff1c34b3b5d8dc74f777Michael Ellerman printf("Error dumping printk buffer!\n"); 2277e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman return; 2278e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman } 2279f312deb4cd0c88196edf6dab192b7d42514398d6Vinay Sridhar 2280e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman catch_memory_errors = 1; 2281e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman sync(); 2282f312deb4cd0c88196edf6dab192b7d42514398d6Vinay Sridhar 2283ca5dd3954a62dc14c2afff1c34b3b5d8dc74f777Michael Ellerman kmsg_dump_rewind_nolock(&dumper); 2284ca5dd3954a62dc14c2afff1c34b3b5d8dc74f777Michael Ellerman while (kmsg_dump_get_line_nolock(&dumper, false, buf, sizeof(buf), &len)) { 2285ca5dd3954a62dc14c2afff1c34b3b5d8dc74f777Michael Ellerman buf[len] = '\0'; 2286ca5dd3954a62dc14c2afff1c34b3b5d8dc74f777Michael Ellerman printf("%s", buf); 2287ca5dd3954a62dc14c2afff1c34b3b5d8dc74f777Michael Ellerman } 2288f312deb4cd0c88196edf6dab192b7d42514398d6Vinay Sridhar 2289e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman sync(); 2290e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman /* wait a little while to see if we get a machine check */ 2291e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman __delay(200); 2292e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman catch_memory_errors = 0; 2293f312deb4cd0c88196edf6dab192b7d42514398d6Vinay Sridhar} 22941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 22961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Memory operations - move, set, print differences 22971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 22981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long mdest; /* destination address */ 22991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long msrc; /* source address */ 23001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long mval; /* byte value to set memory to */ 23011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long mcount; /* # bytes to affect */ 23021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long mdiffs; /* max # differences to print */ 23031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23049f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void 23051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmemops(int cmd) 23061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 23071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scanhex((void *)&mdest); 23081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( termch != '\n' ) 23091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds termch = 0; 23101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scanhex((void *)(cmd == 's'? &mval: &msrc)); 23111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( termch != '\n' ) 23121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds termch = 0; 23131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scanhex((void *)&mcount); 23141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch( cmd ){ 23151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'm': 23161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memmove((void *)mdest, (void *)msrc, mcount); 23171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 23181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 's': 23191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset((void *)mdest, mval, mcount); 23201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 23211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'd': 23221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( termch != '\n' ) 23231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds termch = 0; 23241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scanhex((void *)&mdiffs); 23251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs); 23261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 23271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 23281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 23291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23309f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void 23311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmemdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr) 23321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 23331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned n, prt; 23341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds prt = 0; 23361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for( n = nb; n > 0; --n ) 23371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( *p1++ != *p2++ ) 23381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( ++prt <= maxpr ) 23391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("%.16x %.2x # %.16x %.2x\n", p1 - 1, 23401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p1[-1], p2 - 1, p2[-1]); 23411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( prt > maxpr ) 23421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("Total of %d differences\n", prt); 23431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 23441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned mend; 23461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned mask; 23471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23489f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void 23491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmemlocate(void) 23501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 23511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned a, n; 23521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char val[4]; 23531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds last_cmd = "ml"; 23551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scanhex((void *)&mdest); 23561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (termch != '\n') { 23571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds termch = 0; 23581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scanhex((void *)&mend); 23591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (termch != '\n') { 23601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds termch = 0; 23611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scanhex((void *)&mval); 23621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mask = ~0; 23631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (termch != '\n') termch = 0; 23641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scanhex((void *)&mask); 23651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 23661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 23671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = 0; 23681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (a = mdest; a < mend; a += 4) { 23691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mread(a, val, 4) == 4 23701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds && ((GETWORD(val) ^ mval) & mask) == 0) { 23711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("%.16x: %.16x\n", a, GETWORD(val)); 23721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (++n >= 10) 23731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 23741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 23751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 23761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 23771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long mskip = 0x1000; 23791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long mlim = 0xffffffff; 23801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23819f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void 23821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmemzcan(void) 23831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 23841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char v; 23851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned a; 23861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ok, ook; 23871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scanhex(&mdest); 23891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (termch != '\n') termch = 0; 23901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scanhex(&mskip); 23911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (termch != '\n') termch = 0; 23921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scanhex(&mlim); 23931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ook = 0; 23941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (a = mdest; a < mlim; a += mskip) { 23951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ok = mread(a, &v, 1); 23961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ok && !ook) { 23971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("%.8x .. ", a); 23981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (!ok && ook) 23991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("%.8x\n", a - mskip); 24001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ook = ok; 24011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (a + mskip < a) 24021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 24031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 24041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ook) 24051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("%.8x\n", a - mskip); 24061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 24071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24089f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void proccall(void) 2409f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras{ 2410f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras unsigned long args[8]; 2411f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras unsigned long ret; 2412f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras int i; 2413f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras typedef unsigned long (*callfunc_t)(unsigned long, unsigned long, 2414f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras unsigned long, unsigned long, unsigned long, 2415f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras unsigned long, unsigned long, unsigned long); 2416f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras callfunc_t func; 2417f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras 2418f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras if (!scanhex(&adrs)) 2419f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras return; 2420f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras if (termch != '\n') 2421f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras termch = 0; 2422f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras for (i = 0; i < 8; ++i) 2423f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras args[i] = 0; 2424f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras for (i = 0; i < 8; ++i) { 2425f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras if (!scanhex(&args[i]) || termch == '\n') 2426f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras break; 2427f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras termch = 0; 2428f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras } 2429f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras func = (callfunc_t) adrs; 2430f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras ret = 0; 2431f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras if (setjmp(bus_error_jmp) == 0) { 2432f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras catch_memory_errors = 1; 2433f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras sync(); 2434f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras ret = func(args[0], args[1], args[2], args[3], 2435f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras args[4], args[5], args[6], args[7]); 2436f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras sync(); 2437736256e4f1bc50bb8198c9b61dffd5fd0de17477Michael Ellerman printf("return value is 0x%lx\n", ret); 2438f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras } else { 2439f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras printf("*** %x exception occurred\n", fault_except); 2440f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras } 2441f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras catch_memory_errors = 0; 2442f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras} 2443f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras 24441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Input scanning routines */ 24451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 24461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsskipbl(void) 24471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 24481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int c; 24491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( termch != 0 ){ 24511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = termch; 24521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds termch = 0; 24531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 24541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = inchar(); 24551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while( c == ' ' || c == '\t' ) 24561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = inchar(); 24571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return c; 24581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 24591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define N_PTREGS 44 24611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char *regnames[N_PTREGS] = { 24621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 24631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 24641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 24651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", 2466f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", 2467f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#ifdef CONFIG_PPC64 2468f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras "softe", 2469f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#else 2470f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras "mq", 2471f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#endif 24721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "trap", "dar", "dsisr", "res" 24731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 24741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 24761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsscanhex(unsigned long *vp) 24771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 24781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int c, d; 24791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long v; 24801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = skipbl(); 24821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c == '%') { 24831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* parse register name */ 24841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char regname[8]; 24851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 24861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < sizeof(regname) - 1; ++i) { 24881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = inchar(); 24891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!isalnum(c)) { 24901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds termch = c; 24911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 24921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 24931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regname[i] = c; 24941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 24951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regname[i] = 0; 24961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < N_PTREGS; ++i) { 24971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (strcmp(regnames[i], regname) == 0) { 24981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (xmon_regs == NULL) { 24991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("regs not available\n"); 25001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 25011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 25021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *vp = ((unsigned long *)xmon_regs)[i]; 25031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 25041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 25051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 25061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("invalid register name '%%%s'\n", regname); 25071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 25081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 25091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* skip leading "0x" if any */ 25111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c == '0') { 25131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = inchar(); 25141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c == 'x') { 25151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = inchar(); 25161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 25171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds d = hexdigit(c); 25181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (d == EOF) { 25191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds termch = c; 25201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *vp = 0; 25211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 25221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 25231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 25241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (c == '$') { 25251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 25261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i=0; i<63; i++) { 25271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = inchar(); 25281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (isspace(c)) { 25291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds termch = c; 25301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 25311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 25321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmpstr[i] = c; 25331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 25341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmpstr[i++] = 0; 25356879dc137ea4efad65cab8bf8a7c0b742bcf92ccBenjamin Herrenschmidt *vp = 0; 25366879dc137ea4efad65cab8bf8a7c0b742bcf92ccBenjamin Herrenschmidt if (setjmp(bus_error_jmp) == 0) { 25376879dc137ea4efad65cab8bf8a7c0b742bcf92ccBenjamin Herrenschmidt catch_memory_errors = 1; 25386879dc137ea4efad65cab8bf8a7c0b742bcf92ccBenjamin Herrenschmidt sync(); 25396879dc137ea4efad65cab8bf8a7c0b742bcf92ccBenjamin Herrenschmidt *vp = kallsyms_lookup_name(tmpstr); 25406879dc137ea4efad65cab8bf8a7c0b742bcf92ccBenjamin Herrenschmidt sync(); 25416879dc137ea4efad65cab8bf8a7c0b742bcf92ccBenjamin Herrenschmidt } 25426879dc137ea4efad65cab8bf8a7c0b742bcf92ccBenjamin Herrenschmidt catch_memory_errors = 0; 25431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(*vp)) { 25441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("unknown symbol '%s'\n", tmpstr); 25451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 25461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 25471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 25481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 25491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds d = hexdigit(c); 25511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (d == EOF) { 25521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds termch = c; 25531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 25541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 25551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds v = 0; 25561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds do { 25571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds v = (v << 4) + d; 25581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = inchar(); 25591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds d = hexdigit(c); 25601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } while (d != EOF); 25611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds termch = c; 25621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *vp = v; 25631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 25641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 25651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25669f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void 25671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsscannl(void) 25681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 25691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int c; 25701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = termch; 25721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds termch = 0; 25731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while( c != '\n' ) 25741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = inchar(); 25751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 25761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25779f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic int hexdigit(int c) 25781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 25791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( '0' <= c && c <= '9' ) 25801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return c - '0'; 25811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( 'A' <= c && c <= 'F' ) 25821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return c - ('A' - 10); 25831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( 'a' <= c && c <= 'f' ) 25841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return c - ('a' - 10); 25851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return EOF; 25861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 25871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid 25891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsgetstring(char *s, int size) 25901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 25911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int c; 25921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = skipbl(); 25941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds do { 25951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( size > 1 ){ 25961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *s++ = c; 25971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds --size; 25981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 25991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = inchar(); 26001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } while( c != ' ' && c != '\t' && c != '\n' ); 26011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds termch = c; 26021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *s = 0; 26031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 26041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char line[256]; 26061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char *lineptr; 26071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26089f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void 26091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsflush_input(void) 26101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 26111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lineptr = NULL; 26121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 26131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26149f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic int 26151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsinchar(void) 26161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 26171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (lineptr == NULL || *lineptr == 0) { 2618fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras if (xmon_gets(line, sizeof(line)) == NULL) { 26191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lineptr = NULL; 26201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return EOF; 26211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 26221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lineptr = line; 26231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 26241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return *lineptr++; 26251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 26261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26279f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void 26281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstake_input(char *str) 26291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 26301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lineptr = str; 26311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 26321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 26351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssymbol_lookup(void) 26361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 26371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int type = inchar(); 26381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long addr; 26391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds static char tmp[64]; 26401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (type) { 26421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 'a': 26431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (scanhex(&addr)) 26441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xmon_print_symbol(addr, ": ", "\n"); 26451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds termch = 0; 26461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 26471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 's': 26481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds getstring(tmp, 64); 26491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (setjmp(bus_error_jmp) == 0) { 26501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds catch_memory_errors = 1; 26511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync(); 26521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds addr = kallsyms_lookup_name(tmp); 26531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (addr) 26541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("%s: %lx\n", tmp, addr); 26551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 26561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("Symbol '%s' not found.\n", tmp); 26571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync(); 26581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 26591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds catch_memory_errors = 0; 26601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds termch = 0; 26611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 26621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 26631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 26641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Print an address in numeric and symbolic form (if possible) */ 26671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void xmon_print_symbol(unsigned long address, const char *mid, 26681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const char *after) 26691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 26701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *modname; 26711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const char *name = NULL; 26721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long offset, size; 26731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2674f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras printf(REG, address); 26751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (setjmp(bus_error_jmp) == 0) { 26761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds catch_memory_errors = 1; 26771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync(); 26781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds name = kallsyms_lookup(address, &size, &offset, &modname, 26791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmpstr); 26801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync(); 26811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* wait a little while to see if we get a machine check */ 26821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __delay(200); 26831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 26841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds catch_memory_errors = 0; 26861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (name) { 26881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("%s%s+%#lx/%#lx", mid, name, offset, size); 26891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (modname) 26901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf(" [%s]", modname); 26911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 26921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("%s", after); 26931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 26941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26952d27cfd3286966c04d4192a9db5a6c7ea60eebf1Benjamin Herrenschmidt#ifdef CONFIG_PPC_BOOK3S_64 269613b3d13b813ab834fac67dc05f8b86dbcc29c134Michael Ellermanvoid dump_segments(void) 26971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 26981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 2699b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt unsigned long esid,vsid,valid; 2700b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt unsigned long llp; 27011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2702736256e4f1bc50bb8198c9b61dffd5fd0de17477Michael Ellerman printf("SLB contents of cpu 0x%x\n", smp_processor_id()); 27031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2704584f8b71a2e8abdaeb4b6f4fddaf542b61392453Michael Neuling for (i = 0; i < mmu_slb_size; i++) { 2705b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i)); 2706b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt asm volatile("slbmfev %0,%1" : "=r" (vsid) : "r" (i)); 2707b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt valid = (esid & SLB_ESID_V); 2708b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt if (valid | esid | vsid) { 2709b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt printf("%02d %016lx %016lx", i, esid, vsid); 2710b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt if (valid) { 2711b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt llp = vsid & SLB_VSID_LLP; 2712b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt if (vsid & SLB_VSID_B_1T) { 2713b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n", 2714b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt GET_ESID_1T(esid), 2715b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T, 2716b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt llp); 2717b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt } else { 2718b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n", 2719b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt GET_ESID(esid), 2720b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT, 2721b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt llp); 2722b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt } 2723b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt } else 2724b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt printf("\n"); 2725b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt } 27261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 27271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2728f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#endif 2729f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras 2730f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#ifdef CONFIG_PPC_STD_MMU_32 2731f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerrasvoid dump_segments(void) 2732f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras{ 2733f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras int i; 2734f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras 2735f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras printf("sr0-15 ="); 2736f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras for (i = 0; i < 16; ++i) 2737f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras printf(" %x", mfsrin(i)); 2738f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras printf("\n"); 2739f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras} 2740f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#endif 2741f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras 27425a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt#ifdef CONFIG_44x 27435a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidtstatic void dump_tlb_44x(void) 27445a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt{ 27455a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt int i; 27465a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt 27475a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt for (i = 0; i < PPC44x_TLB_SIZE; i++) { 27485a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt unsigned long w0,w1,w2; 27495a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt asm volatile("tlbre %0,%1,0" : "=r" (w0) : "r" (i)); 27505a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt asm volatile("tlbre %0,%1,1" : "=r" (w1) : "r" (i)); 27515a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt asm volatile("tlbre %0,%1,2" : "=r" (w2) : "r" (i)); 27525a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt printf("[%02x] %08x %08x %08x ", i, w0, w1, w2); 27535a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt if (w0 & PPC44x_TLB_VALID) { 27545a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt printf("V %08x -> %01x%08x %c%c%c%c%c", 27555a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt w0 & PPC44x_TLB_EPN_MASK, 27565a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt w1 & PPC44x_TLB_ERPN_MASK, 27575a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt w1 & PPC44x_TLB_RPN_MASK, 27585a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt (w2 & PPC44x_TLB_W) ? 'W' : 'w', 27595a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt (w2 & PPC44x_TLB_I) ? 'I' : 'i', 27605a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt (w2 & PPC44x_TLB_M) ? 'M' : 'm', 27615a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt (w2 & PPC44x_TLB_G) ? 'G' : 'g', 27625a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt (w2 & PPC44x_TLB_E) ? 'E' : 'e'); 27635a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt } 27645a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt printf("\n"); 27655a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt } 27665a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt} 27675a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt#endif /* CONFIG_44x */ 27689f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellerman 276903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt#ifdef CONFIG_PPC_BOOK3E 277003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidtstatic void dump_tlb_book3e(void) 277103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt{ 277203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt u32 mmucfg, pidmask, lpidmask; 277303247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt u64 ramask; 277403247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt int i, tlb, ntlbs, pidsz, lpidsz, rasz, lrat = 0; 277503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt int mmu_version; 277603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt static const char *pgsz_names[] = { 277703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt " 1K", 277803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt " 2K", 277903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt " 4K", 278003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt " 8K", 278103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt " 16K", 278203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt " 32K", 278303247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt " 64K", 278403247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt "128K", 278503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt "256K", 278603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt "512K", 278703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt " 1M", 278803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt " 2M", 278903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt " 4M", 279003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt " 8M", 279103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt " 16M", 279203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt " 32M", 279303247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt " 64M", 279403247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt "128M", 279503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt "256M", 279603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt "512M", 279703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt " 1G", 279803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt " 2G", 279903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt " 4G", 280003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt " 8G", 280103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt " 16G", 280203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt " 32G", 280303247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt " 64G", 280403247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt "128G", 280503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt "256G", 280603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt "512G", 280703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt " 1T", 280803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt " 2T", 280903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt }; 281003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt 281103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt /* Gather some infos about the MMU */ 281203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt mmucfg = mfspr(SPRN_MMUCFG); 281303247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt mmu_version = (mmucfg & 3) + 1; 281403247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt ntlbs = ((mmucfg >> 2) & 3) + 1; 281503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt pidsz = ((mmucfg >> 6) & 0x1f) + 1; 281603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt lpidsz = (mmucfg >> 24) & 0xf; 281703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt rasz = (mmucfg >> 16) & 0x7f; 281803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt if ((mmu_version > 1) && (mmucfg & 0x10000)) 281903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt lrat = 1; 282003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n", 282103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt mmu_version, ntlbs, pidsz, lpidsz, rasz); 282203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt pidmask = (1ul << pidsz) - 1; 282303247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt lpidmask = (1ul << lpidsz) - 1; 282403247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt ramask = (1ull << rasz) - 1; 282503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt 282603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt for (tlb = 0; tlb < ntlbs; tlb++) { 282703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt u32 tlbcfg; 282803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt int nent, assoc, new_cc = 1; 282903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt printf("TLB %d:\n------\n", tlb); 283003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt switch(tlb) { 283103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt case 0: 283203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt tlbcfg = mfspr(SPRN_TLB0CFG); 283303247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt break; 283403247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt case 1: 283503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt tlbcfg = mfspr(SPRN_TLB1CFG); 283603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt break; 283703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt case 2: 283803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt tlbcfg = mfspr(SPRN_TLB2CFG); 283903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt break; 284003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt case 3: 284103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt tlbcfg = mfspr(SPRN_TLB3CFG); 284203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt break; 284303247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt default: 284403247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt printf("Unsupported TLB number !\n"); 284503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt continue; 284603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt } 284703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt nent = tlbcfg & 0xfff; 284803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt assoc = (tlbcfg >> 24) & 0xff; 284903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt for (i = 0; i < nent; i++) { 285003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt u32 mas0 = MAS0_TLBSEL(tlb); 285103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt u32 mas1 = MAS1_TSIZE(BOOK3E_PAGESZ_4K); 285203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt u64 mas2 = 0; 285303247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt u64 mas7_mas3; 285403247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt int esel = i, cc = i; 285503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt 285603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt if (assoc != 0) { 285703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt cc = i / assoc; 285803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt esel = i % assoc; 285903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt mas2 = cc * 0x1000; 286003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt } 286103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt 286203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt mas0 |= MAS0_ESEL(esel); 286303247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt mtspr(SPRN_MAS0, mas0); 286403247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt mtspr(SPRN_MAS1, mas1); 286503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt mtspr(SPRN_MAS2, mas2); 286603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt asm volatile("tlbre 0,0,0" : : : "memory"); 286703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt mas1 = mfspr(SPRN_MAS1); 286803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt mas2 = mfspr(SPRN_MAS2); 286903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt mas7_mas3 = mfspr(SPRN_MAS7_MAS3); 287003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt if (assoc && (i % assoc) == 0) 287103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt new_cc = 1; 287203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt if (!(mas1 & MAS1_VALID)) 287303247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt continue; 287403247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt if (assoc == 0) 287503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt printf("%04x- ", i); 287603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt else if (new_cc) 287703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt printf("%04x-%c", cc, 'A' + esel); 287803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt else 287903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt printf(" |%c", 'A' + esel); 288003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt new_cc = 0; 288103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt printf(" %016llx %04x %s %c%c AS%c", 288203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt mas2 & ~0x3ffull, 288303247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt (mas1 >> 16) & 0x3fff, 288403247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt pgsz_names[(mas1 >> 7) & 0x1f], 288503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt mas1 & MAS1_IND ? 'I' : ' ', 288603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt mas1 & MAS1_IPROT ? 'P' : ' ', 288703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt mas1 & MAS1_TS ? '1' : '0'); 288803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt printf(" %c%c%c%c%c%c%c", 288903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt mas2 & MAS2_X0 ? 'a' : ' ', 289003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt mas2 & MAS2_X1 ? 'v' : ' ', 289103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt mas2 & MAS2_W ? 'w' : ' ', 289203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt mas2 & MAS2_I ? 'i' : ' ', 289303247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt mas2 & MAS2_M ? 'm' : ' ', 289403247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt mas2 & MAS2_G ? 'g' : ' ', 289503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt mas2 & MAS2_E ? 'e' : ' '); 289603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt printf(" %016llx", mas7_mas3 & ramask & ~0x7ffull); 289703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt if (mas1 & MAS1_IND) 289803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt printf(" %s\n", 289903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt pgsz_names[(mas7_mas3 >> 1) & 0x1f]); 290003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt else 290103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt printf(" U%c%c%c S%c%c%c\n", 290203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt mas7_mas3 & MAS3_UX ? 'x' : ' ', 290303247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt mas7_mas3 & MAS3_UW ? 'w' : ' ', 290403247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt mas7_mas3 & MAS3_UR ? 'r' : ' ', 290503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt mas7_mas3 & MAS3_SX ? 'x' : ' ', 290603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt mas7_mas3 & MAS3_SW ? 'w' : ' ', 290703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt mas7_mas3 & MAS3_SR ? 'r' : ' '); 290803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt } 290903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt } 291003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt} 291103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt#endif /* CONFIG_PPC_BOOK3E */ 291203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt 29139f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void xmon_init(int enable) 2914b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering{ 2915b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering if (enable) { 2916b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering __debugger = xmon; 2917b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering __debugger_ipi = xmon_ipi; 2918b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering __debugger_bpt = xmon_bpt; 2919b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering __debugger_sstep = xmon_sstep; 2920b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering __debugger_iabr_match = xmon_iabr_match; 29219422de3e953d0e60eb95f5430a9dd803eec1c6d7Michael Neuling __debugger_break_match = xmon_break_match; 2922b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering __debugger_fault_handler = xmon_fault_handler; 2923b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering } else { 2924b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering __debugger = NULL; 2925b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering __debugger_ipi = NULL; 2926b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering __debugger_bpt = NULL; 2927b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering __debugger_sstep = NULL; 2928b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering __debugger_iabr_match = NULL; 29299422de3e953d0e60eb95f5430a9dd803eec1c6d7Michael Neuling __debugger_break_match = NULL; 2930b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering __debugger_fault_handler = NULL; 2931b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering } 29321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2933fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras 2934fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras#ifdef CONFIG_MAGIC_SYSRQ 29351495cc9df4e81f5a8fa9b0b8f1034b14d24b7d8cDmitry Torokhovstatic void sysrq_handle_xmon(int key) 2936fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras{ 2937fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras /* ensure xmon is enabled */ 2938fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras xmon_init(1); 29397d12e780e003f93433d49ce78cfedf4b4c52adc5David Howells debugger(get_irq_regs()); 2940fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras} 2941fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras 29421495cc9df4e81f5a8fa9b0b8f1034b14d24b7d8cDmitry Torokhovstatic struct sysrq_key_op sysrq_xmon_op = { 2943fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras .handler = sysrq_handle_xmon, 294490a102e59ab9c94071fe1993134daff462d17a3fzhangwei(Jovi) .help_msg = "xmon(x)", 2945fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras .action_msg = "Entering xmon", 2946fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras}; 2947fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras 2948fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerrasstatic int __init setup_xmon_sysrq(void) 2949fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras{ 2950fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras register_sysrq_key('x', &sysrq_xmon_op); 2951fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras return 0; 2952fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras} 2953fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras__initcall(setup_xmon_sysrq); 2954fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras#endif /* CONFIG_MAGIC_SYSRQ */ 2955476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman 2956f5e6a280d153bff3b0cd15651d29d409f8dea698Olaf Heringstatic int __initdata xmon_early, xmon_off; 2957476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman 2958476792839467c08ddeedd8b44a7423d415b68259Michael Ellermanstatic int __init early_parse_xmon(char *p) 2959476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman{ 2960476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman if (!p || strncmp(p, "early", 5) == 0) { 2961476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman /* just "xmon" is equivalent to "xmon=early" */ 2962476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman xmon_init(1); 2963476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman xmon_early = 1; 2964476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman } else if (strncmp(p, "on", 2) == 0) 2965476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman xmon_init(1); 2966476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman else if (strncmp(p, "off", 3) == 0) 2967476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman xmon_off = 1; 2968476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman else if (strncmp(p, "nobt", 4) == 0) 2969476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman xmon_no_auto_backtrace = 1; 2970476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman else 2971476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman return 1; 2972476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman 2973476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman return 0; 2974476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman} 2975476792839467c08ddeedd8b44a7423d415b68259Michael Ellermanearly_param("xmon", early_parse_xmon); 2976476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman 2977476792839467c08ddeedd8b44a7423d415b68259Michael Ellermanvoid __init xmon_setup(void) 2978476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman{ 2979476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman#ifdef CONFIG_XMON_DEFAULT 2980476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman if (!xmon_off) 2981476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman xmon_init(1); 2982476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman#endif 2983476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman if (xmon_early) 2984476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman debugger(NULL); 2985476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman} 2986ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman 2987e055595d3e5f5233374211bc6893e5d16976df99Arnd Bergmann#ifdef CONFIG_SPU_BASE 2988ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman 2989ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellermanstruct spu_info { 2990ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman struct spu *spu; 2991ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman u64 saved_mfc_sr1_RW; 2992ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman u32 saved_spu_runcntl_RW; 299324a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman unsigned long dump_addr; 2994ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman u8 stopped_ok; 2995ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman}; 2996ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman 2997ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman#define XMON_NUM_SPUS 16 /* Enough for current hardware */ 2998ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman 2999ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellermanstatic struct spu_info spu_info[XMON_NUM_SPUS]; 3000ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman 3001ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellermanvoid xmon_register_spus(struct list_head *list) 3002ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman{ 3003ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman struct spu *spu; 3004ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman 3005ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman list_for_each_entry(spu, list, full_list) { 3006ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman if (spu->number >= XMON_NUM_SPUS) { 3007ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman WARN_ON(1); 3008ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman continue; 3009ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman } 3010ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman 3011ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman spu_info[spu->number].spu = spu; 3012ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman spu_info[spu->number].stopped_ok = 0; 301324a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman spu_info[spu->number].dump_addr = (unsigned long) 301424a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman spu_info[spu->number].spu->local_store; 3015ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman } 3016ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman} 3017ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman 3018ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellermanstatic void stop_spus(void) 3019ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman{ 3020ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman struct spu *spu; 3021ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman int i; 3022ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman u64 tmp; 3023ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman 3024ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman for (i = 0; i < XMON_NUM_SPUS; i++) { 3025ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman if (!spu_info[i].spu) 3026ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman continue; 3027ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman 3028ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman if (setjmp(bus_error_jmp) == 0) { 3029ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman catch_memory_errors = 1; 3030ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman sync(); 3031ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman 3032ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman spu = spu_info[i].spu; 3033ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman 3034ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman spu_info[i].saved_spu_runcntl_RW = 3035ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman in_be32(&spu->problem->spu_runcntl_RW); 3036ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman 3037ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman tmp = spu_mfc_sr1_get(spu); 3038ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman spu_info[i].saved_mfc_sr1_RW = tmp; 3039ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman 3040ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK; 3041ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman spu_mfc_sr1_set(spu, tmp); 3042ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman 3043ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman sync(); 3044ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman __delay(200); 3045ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman 3046ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman spu_info[i].stopped_ok = 1; 30472a14442bfebfea23d004fa4dfd067a94f5720ed7Michael Ellerman 30482a14442bfebfea23d004fa4dfd067a94f5720ed7Michael Ellerman printf("Stopped spu %.2d (was %s)\n", i, 30492a14442bfebfea23d004fa4dfd067a94f5720ed7Michael Ellerman spu_info[i].saved_spu_runcntl_RW ? 30502a14442bfebfea23d004fa4dfd067a94f5720ed7Michael Ellerman "running" : "stopped"); 3051ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman } else { 3052ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman catch_memory_errors = 0; 3053ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman printf("*** Error stopping spu %.2d\n", i); 3054ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman } 3055ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman catch_memory_errors = 0; 3056ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman } 3057ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman} 3058ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman 3059ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellermanstatic void restart_spus(void) 3060ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman{ 3061ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman struct spu *spu; 3062ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman int i; 3063ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman 3064ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman for (i = 0; i < XMON_NUM_SPUS; i++) { 3065ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman if (!spu_info[i].spu) 3066ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman continue; 3067ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman 3068ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman if (!spu_info[i].stopped_ok) { 3069ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman printf("*** Error, spu %d was not successfully stopped" 3070ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman ", not restarting\n", i); 3071ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman continue; 3072ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman } 3073ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman 3074ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman if (setjmp(bus_error_jmp) == 0) { 3075ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman catch_memory_errors = 1; 3076ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman sync(); 3077ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman 3078ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman spu = spu_info[i].spu; 3079ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW); 3080ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman out_be32(&spu->problem->spu_runcntl_RW, 3081ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman spu_info[i].saved_spu_runcntl_RW); 3082ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman 3083ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman sync(); 3084ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman __delay(200); 3085ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman 3086ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman printf("Restarted spu %.2d\n", i); 3087ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman } else { 3088ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman catch_memory_errors = 0; 3089ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman printf("*** Error restarting spu %.2d\n", i); 3090ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman } 3091ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman catch_memory_errors = 0; 3092ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman } 3093ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman} 3094ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman 3095a898497088f46252e6750405504064e2dce53117Michael Ellerman#define DUMP_WIDTH 23 3096437a0706837d09d8ab071c6790da07d9d6bb3d22Michael Ellerman#define DUMP_VALUE(format, field, value) \ 3097a898497088f46252e6750405504064e2dce53117Michael Ellermando { \ 3098a898497088f46252e6750405504064e2dce53117Michael Ellerman if (setjmp(bus_error_jmp) == 0) { \ 3099a898497088f46252e6750405504064e2dce53117Michael Ellerman catch_memory_errors = 1; \ 3100a898497088f46252e6750405504064e2dce53117Michael Ellerman sync(); \ 3101a898497088f46252e6750405504064e2dce53117Michael Ellerman printf(" %-*s = "format"\n", DUMP_WIDTH, \ 3102437a0706837d09d8ab071c6790da07d9d6bb3d22Michael Ellerman #field, value); \ 3103a898497088f46252e6750405504064e2dce53117Michael Ellerman sync(); \ 3104a898497088f46252e6750405504064e2dce53117Michael Ellerman __delay(200); \ 3105a898497088f46252e6750405504064e2dce53117Michael Ellerman } else { \ 3106a898497088f46252e6750405504064e2dce53117Michael Ellerman catch_memory_errors = 0; \ 3107a898497088f46252e6750405504064e2dce53117Michael Ellerman printf(" %-*s = *** Error reading field.\n", \ 3108a898497088f46252e6750405504064e2dce53117Michael Ellerman DUMP_WIDTH, #field); \ 3109a898497088f46252e6750405504064e2dce53117Michael Ellerman } \ 3110a898497088f46252e6750405504064e2dce53117Michael Ellerman catch_memory_errors = 0; \ 3111a898497088f46252e6750405504064e2dce53117Michael Ellerman} while (0) 3112a898497088f46252e6750405504064e2dce53117Michael Ellerman 3113437a0706837d09d8ab071c6790da07d9d6bb3d22Michael Ellerman#define DUMP_FIELD(obj, format, field) \ 3114437a0706837d09d8ab071c6790da07d9d6bb3d22Michael Ellerman DUMP_VALUE(format, field, obj->field) 3115437a0706837d09d8ab071c6790da07d9d6bb3d22Michael Ellerman 3116a898497088f46252e6750405504064e2dce53117Michael Ellermanstatic void dump_spu_fields(struct spu *spu) 3117a898497088f46252e6750405504064e2dce53117Michael Ellerman{ 3118a898497088f46252e6750405504064e2dce53117Michael Ellerman printf("Dumping spu fields at address %p:\n", spu); 3119a898497088f46252e6750405504064e2dce53117Michael Ellerman 3120a898497088f46252e6750405504064e2dce53117Michael Ellerman DUMP_FIELD(spu, "0x%x", number); 3121a898497088f46252e6750405504064e2dce53117Michael Ellerman DUMP_FIELD(spu, "%s", name); 3122a898497088f46252e6750405504064e2dce53117Michael Ellerman DUMP_FIELD(spu, "0x%lx", local_store_phys); 3123a898497088f46252e6750405504064e2dce53117Michael Ellerman DUMP_FIELD(spu, "0x%p", local_store); 3124a898497088f46252e6750405504064e2dce53117Michael Ellerman DUMP_FIELD(spu, "0x%lx", ls_size); 3125a898497088f46252e6750405504064e2dce53117Michael Ellerman DUMP_FIELD(spu, "0x%x", node); 3126a898497088f46252e6750405504064e2dce53117Michael Ellerman DUMP_FIELD(spu, "0x%lx", flags); 3127a898497088f46252e6750405504064e2dce53117Michael Ellerman DUMP_FIELD(spu, "%d", class_0_pending); 3128f3d69e0507f84903059d456c5d19f10b2df3ac69Luke Browning DUMP_FIELD(spu, "0x%lx", class_0_dar); 3129f3d69e0507f84903059d456c5d19f10b2df3ac69Luke Browning DUMP_FIELD(spu, "0x%lx", class_1_dar); 3130f3d69e0507f84903059d456c5d19f10b2df3ac69Luke Browning DUMP_FIELD(spu, "0x%lx", class_1_dsisr); 3131a898497088f46252e6750405504064e2dce53117Michael Ellerman DUMP_FIELD(spu, "0x%lx", irqs[0]); 3132a898497088f46252e6750405504064e2dce53117Michael Ellerman DUMP_FIELD(spu, "0x%lx", irqs[1]); 3133a898497088f46252e6750405504064e2dce53117Michael Ellerman DUMP_FIELD(spu, "0x%lx", irqs[2]); 3134a898497088f46252e6750405504064e2dce53117Michael Ellerman DUMP_FIELD(spu, "0x%x", slb_replace); 3135a898497088f46252e6750405504064e2dce53117Michael Ellerman DUMP_FIELD(spu, "%d", pid); 3136a898497088f46252e6750405504064e2dce53117Michael Ellerman DUMP_FIELD(spu, "0x%p", mm); 3137a898497088f46252e6750405504064e2dce53117Michael Ellerman DUMP_FIELD(spu, "0x%p", ctx); 3138a898497088f46252e6750405504064e2dce53117Michael Ellerman DUMP_FIELD(spu, "0x%p", rq); 3139a898497088f46252e6750405504064e2dce53117Michael Ellerman DUMP_FIELD(spu, "0x%p", timestamp); 3140a898497088f46252e6750405504064e2dce53117Michael Ellerman DUMP_FIELD(spu, "0x%lx", problem_phys); 3141a898497088f46252e6750405504064e2dce53117Michael Ellerman DUMP_FIELD(spu, "0x%p", problem); 3142437a0706837d09d8ab071c6790da07d9d6bb3d22Michael Ellerman DUMP_VALUE("0x%x", problem->spu_runcntl_RW, 3143437a0706837d09d8ab071c6790da07d9d6bb3d22Michael Ellerman in_be32(&spu->problem->spu_runcntl_RW)); 3144437a0706837d09d8ab071c6790da07d9d6bb3d22Michael Ellerman DUMP_VALUE("0x%x", problem->spu_status_R, 3145437a0706837d09d8ab071c6790da07d9d6bb3d22Michael Ellerman in_be32(&spu->problem->spu_status_R)); 3146437a0706837d09d8ab071c6790da07d9d6bb3d22Michael Ellerman DUMP_VALUE("0x%x", problem->spu_npc_RW, 3147437a0706837d09d8ab071c6790da07d9d6bb3d22Michael Ellerman in_be32(&spu->problem->spu_npc_RW)); 3148a898497088f46252e6750405504064e2dce53117Michael Ellerman DUMP_FIELD(spu, "0x%p", priv2); 3149a985239bdf017e00e985c3a31149d6ae128fdc5fMichael Ellerman DUMP_FIELD(spu, "0x%p", pdata); 3150a898497088f46252e6750405504064e2dce53117Michael Ellerman} 3151a898497088f46252e6750405504064e2dce53117Michael Ellerman 3152af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellermanint 3153af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellermanspu_inst_dump(unsigned long adr, long count, int praddr) 3154af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman{ 3155af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman return generic_inst_dump(adr, count, praddr, print_insn_spu); 3156af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman} 3157af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman 3158af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellermanstatic void dump_spu_ls(unsigned long num, int subcmd) 315924a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman{ 316024a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman unsigned long offset, addr, ls_addr; 316124a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman 316224a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman if (setjmp(bus_error_jmp) == 0) { 316324a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman catch_memory_errors = 1; 316424a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman sync(); 316524a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman ls_addr = (unsigned long)spu_info[num].spu->local_store; 316624a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman sync(); 316724a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman __delay(200); 316824a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman } else { 316924a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman catch_memory_errors = 0; 317024a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman printf("*** Error: accessing spu info for spu %d\n", num); 317124a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman return; 317224a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman } 317324a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman catch_memory_errors = 0; 317424a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman 317524a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman if (scanhex(&offset)) 317624a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman addr = ls_addr + offset; 317724a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman else 317824a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman addr = spu_info[num].dump_addr; 317924a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman 318024a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman if (addr >= ls_addr + LS_SIZE) { 318124a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman printf("*** Error: address outside of local store\n"); 318224a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman return; 318324a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman } 318424a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman 3185af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman switch (subcmd) { 3186af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman case 'i': 3187af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman addr += spu_inst_dump(addr, 16, 1); 3188af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman last_cmd = "sdi\n"; 3189af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman break; 3190af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman default: 3191af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman prdump(addr, 64); 3192af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman addr += 64; 3193af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman last_cmd = "sd\n"; 3194af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman break; 3195af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman } 319624a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman 319724a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman spu_info[num].dump_addr = addr; 319824a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman} 319924a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman 3200ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellermanstatic int do_spu_cmd(void) 3201ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman{ 320224a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman static unsigned long num = 0; 3203af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman int cmd, subcmd = 0; 3204ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman 3205ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman cmd = inchar(); 3206ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman switch (cmd) { 3207ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman case 's': 3208ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman stop_spus(); 3209ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman break; 3210ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman case 'r': 3211ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman restart_spus(); 3212ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman break; 321324a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman case 'd': 3214af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman subcmd = inchar(); 3215af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman if (isxdigit(subcmd) || subcmd == '\n') 3216af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman termch = subcmd; 3217af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman case 'f': 321824a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman scanhex(&num); 321924a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman if (num >= XMON_NUM_SPUS || !spu_info[num].spu) { 3220a898497088f46252e6750405504064e2dce53117Michael Ellerman printf("*** Error: invalid spu number\n"); 322124a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman return 0; 322224a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman } 322324a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman 322424a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman switch (cmd) { 322524a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman case 'f': 322624a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman dump_spu_fields(spu_info[num].spu); 322724a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman break; 322824a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman default: 3229af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman dump_spu_ls(num, subcmd); 323024a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman break; 323124a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman } 323224a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman 3233a898497088f46252e6750405504064e2dce53117Michael Ellerman break; 3234ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman default: 3235ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman return -1; 3236ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman } 3237ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman 3238ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman return 0; 3239ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman} 3240e055595d3e5f5233374211bc6893e5d16976df99Arnd Bergmann#else /* ! CONFIG_SPU_BASE */ 3241ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellermanstatic int do_spu_cmd(void) 3242ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman{ 3243ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman return -1; 3244ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman} 3245ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman#endif 3246