#include <linux/cpumask.h>
#include <linux/module.h>
#include <linux/sysrq.h>
+#include <linux/interrupt.h>
#include <asm/ptrace.h>
#include <asm/string.h>
di dump instructions\n\
df dump float values\n\
dd dump double values\n\
+ dr dump stream of raw bytes\n\
e print exception information\n\
f flush cache\n\
la lookup symbol+offset of specified address\n\
}
#endif
-int xmon_core(struct pt_regs *regs, int fromipi)
+static int xmon_core(struct pt_regs *regs, int fromipi)
{
int cmd = 0;
unsigned long msr;
leave:
cpu_clear(cpu, cpus_in_xmon);
xmon_fault_jmp[cpu] = NULL;
-
#else
/* UP is simple... */
if (in_xmon) {
return IRQ_HANDLED;
}
-int xmon_bpt(struct pt_regs *regs)
+static int xmon_bpt(struct pt_regs *regs)
{
struct bpt *bp;
unsigned long offset;
return 1;
}
-int xmon_sstep(struct pt_regs *regs)
+static int xmon_sstep(struct pt_regs *regs)
{
if (user_mode(regs))
return 0;
return 1;
}
-int xmon_dabr_match(struct pt_regs *regs)
+static int xmon_dabr_match(struct pt_regs *regs)
{
if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
return 0;
return 1;
}
-int xmon_iabr_match(struct pt_regs *regs)
+static int xmon_iabr_match(struct pt_regs *regs)
{
if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
return 0;
return 1;
}
-int xmon_ipi(struct pt_regs *regs)
+static int xmon_ipi(struct pt_regs *regs)
{
#ifdef CONFIG_SMP
if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
return 0;
}
-int xmon_fault_handler(struct pt_regs *regs)
+static int xmon_fault_handler(struct pt_regs *regs)
{
struct bpt *bp;
unsigned long offset;
break;
case 'x':
case 'X':
+ return cmd;
case EOF:
+ printf(" <no input ...>\n");
+ mdelay(2000);
return cmd;
case '?':
printf(help_string);
unsigned int instr;
addr &= ~3;
- if (addr < KERNELBASE) {
+ if (!is_kernel_addr(addr)) {
printf("Breakpoints may only be placed at kernel addresses\n");
return 0;
}
dabr.address = 0;
dabr.enabled = 0;
if (scanhex(&dabr.address)) {
- if (dabr.address < KERNELBASE) {
+ if (!is_kernel_addr(dabr.address)) {
printf(badaddr);
break;
}
{
unsigned int instrs[2];
unsigned long (*code)(void);
- unsigned long opd[3];
unsigned long ret = -1UL;
+#ifdef CONFIG_PPC64
+ unsigned long opd[3];
- instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
- instrs[1] = 0x4e800020;
opd[0] = (unsigned long)instrs;
opd[1] = 0;
opd[2] = 0;
+ code = (unsigned long (*)(void)) opd;
+#else
+ code = (unsigned long (*)(void)) instrs;
+#endif
+
+ /* mfspr r3,n; blr */
+ instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
+ instrs[1] = 0x4e800020;
store_inst(instrs);
store_inst(instrs+1);
- code = (unsigned long (*)(void)) opd;
if (setjmp(bus_error_jmp) == 0) {
catch_memory_errors = 1;
{
unsigned int instrs[2];
unsigned long (*code)(unsigned long);
+#ifdef CONFIG_PPC64
unsigned long opd[3];
- instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
- instrs[1] = 0x4e800020;
opd[0] = (unsigned long)instrs;
opd[1] = 0;
opd[2] = 0;
+ code = (unsigned long (*)(unsigned long)) opd;
+#else
+ code = (unsigned long (*)(unsigned long)) instrs;
+#endif
+
+ instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
+ instrs[1] = 0x4e800020;
store_inst(instrs);
store_inst(instrs+1);
- code = (unsigned long (*)(unsigned long)) opd;
if (setjmp(bus_error_jmp) == 0) {
catch_memory_errors = 1;
return c;
}
+static void xmon_rawdump (unsigned long adrs, long ndump)
+{
+ long n, m, r, nr;
+ unsigned char temp[16];
+
+ for (n = ndump; n > 0;) {
+ r = n < 16? n: 16;
+ nr = mread(adrs, temp, r);
+ adrs += nr;
+ for (m = 0; m < r; ++m) {
+ if (m < nr)
+ printf("%.2x", temp[m]);
+ else
+ printf("%s", fault_chars[fault_type]);
+ }
+ n -= r;
+ if (nr < r)
+ break;
+ }
+ printf("\n");
+}
+
#define isxdigit(c) (('0' <= (c) && (c) <= '9') \
|| ('a' <= (c) && (c) <= 'f') \
|| ('A' <= (c) && (c) <= 'F'))
nidump = MAX_DUMP;
adrs += ppc_inst_dump(adrs, nidump, 1);
last_cmd = "di\n";
+ } else if (c == 'r') {
+ scanhex(&ndump);
+ if (ndump == 0)
+ ndump = 64;
+ xmon_rawdump(adrs, ndump);
+ adrs += ndump;
+ last_cmd = "dr\n";
} else {
scanhex(&ndump);
if (ndump == 0)