[POWERPC] Don't try to just continue if xmon has no input device
[sfrench/cifs-2.6.git] / arch / powerpc / xmon / xmon.c
index 179b10ced8c773ee75d6c5dfb290dd35b84d25f0..708236f3474612a2aad9fc252a458cf1d270e7fc 100644 (file)
@@ -2,6 +2,8 @@
  * 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
@@ -137,10 +139,14 @@ static void bootcmds(void);
 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);
@@ -499,7 +505,7 @@ static int xmon_core(struct pt_regs *regs, int fromipi)
 
        mtmsr(msr);             /* restore interrupt enable */
 
-       return cmd != 'X';
+       return cmd != 'X' && cmd != EOF;
 }
 
 int xmon(struct pt_regs *excp)
@@ -736,6 +742,12 @@ cmds(struct pt_regs *excp)
 
        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());
@@ -2587,3 +2599,34 @@ static int __init setup_xmon_sysrq(void)
 }
 __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);
+}