* Routines providing a simple monitor for use on the PowerMac.
*
* Copyright (C) 1996-2005 Paul Mackerras.
+ * Copyright (C) 2001 PPC64 Team, IBM Corp
+ * Copyrignt (C) 2006 Michael Ellerman, IBM Corp
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/config.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/smp.h>
#include <linux/module.h>
#include <linux/sysrq.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <asm/ptrace.h>
#include <asm/string.h>
#include <asm/rtas.h>
#include <asm/sstep.h>
#include <asm/bug.h>
+#include <asm/irq_regs.h>
#ifdef CONFIG_PPC64
#include <asm/hvcall.h>
static void proccall(void);
void dump_segments(void);
static void symbol_lookup(void);
+static void xmon_show_stack(unsigned long sp, unsigned long lr,
+ unsigned long pc);
static void xmon_print_symbol(unsigned long address, const char *mid,
const char *after);
static const char *getvecname(unsigned long vec);
+int xmon_no_auto_backtrace;
+
extern int print_insn_powerpc(unsigned long, unsigned long, int);
extern void xmon_enter(void);
mtmsr(msr); /* restore interrupt enable */
- return cmd != 'X';
+ return cmd != 'X' && cmd != EOF;
}
int xmon(struct pt_regs *excp)
}
EXPORT_SYMBOL(xmon);
-irqreturn_t
-xmon_irq(int irq, void *d, struct pt_regs *regs)
+irqreturn_t xmon_irq(int irq, void *d)
{
unsigned long flags;
local_irq_save(flags);
printf("Keyboard interrupt\n");
- xmon(regs);
+ xmon(get_irq_regs());
local_irq_restore(flags);
return IRQ_HANDLED;
}
last_cmd = NULL;
xmon_regs = excp;
+
+ if (!xmon_no_auto_backtrace) {
+ xmon_no_auto_backtrace = 1;
+ xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
+ }
+
for(;;) {
#ifdef CONFIG_SMP
printf("%x:", smp_processor_id());
}
#ifdef CONFIG_MAGIC_SYSRQ
-static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs,
- struct tty_struct *tty)
+static void sysrq_handle_xmon(int key, struct tty_struct *tty)
{
/* ensure xmon is enabled */
xmon_init(1);
- debugger(pt_regs);
+ debugger(get_irq_regs());
}
static struct sysrq_key_op sysrq_xmon_op =
}
__initcall(setup_xmon_sysrq);
#endif /* CONFIG_MAGIC_SYSRQ */
+
+int __initdata xmon_early, xmon_off;
+
+static int __init early_parse_xmon(char *p)
+{
+ if (!p || strncmp(p, "early", 5) == 0) {
+ /* just "xmon" is equivalent to "xmon=early" */
+ xmon_init(1);
+ xmon_early = 1;
+ } else if (strncmp(p, "on", 2) == 0)
+ xmon_init(1);
+ else if (strncmp(p, "off", 3) == 0)
+ xmon_off = 1;
+ else if (strncmp(p, "nobt", 4) == 0)
+ xmon_no_auto_backtrace = 1;
+ else
+ return 1;
+
+ return 0;
+}
+early_param("xmon", early_parse_xmon);
+
+void __init xmon_setup(void)
+{
+#ifdef CONFIG_XMON_DEFAULT
+ if (!xmon_off)
+ xmon_init(1);
+#endif
+ if (xmon_early)
+ debugger(NULL);
+}