|
@@ -1,7 +1,7 @@
|
|
|
/*
|
|
|
* SuperH KGDB support
|
|
|
*
|
|
|
- * Copyright (C) 2008 Paul Mundt
|
|
|
+ * Copyright (C) 2008 - 2009 Paul Mundt
|
|
|
*
|
|
|
* Single stepping taken from the old stub by Henry Bell and Jeremy Siegel.
|
|
|
*
|
|
@@ -251,24 +251,60 @@ BUILD_TRAP_HANDLER(singlestep)
|
|
|
local_irq_restore(flags);
|
|
|
}
|
|
|
|
|
|
+static int __kgdb_notify(struct die_args *args, unsigned long cmd)
|
|
|
+{
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ switch (cmd) {
|
|
|
+ case DIE_BREAKPOINT:
|
|
|
+ /*
|
|
|
+ * This means a user thread is single stepping
|
|
|
+ * a system call which should be ignored
|
|
|
+ */
|
|
|
+ if (test_thread_flag(TIF_SINGLESTEP))
|
|
|
+ return NOTIFY_DONE;
|
|
|
+
|
|
|
+ ret = kgdb_handle_exception(args->trapnr & 0xff, args->signr,
|
|
|
+ args->err, args->regs);
|
|
|
+ if (ret)
|
|
|
+ return NOTIFY_DONE;
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
-BUILD_TRAP_HANDLER(breakpoint)
|
|
|
+ return NOTIFY_STOP;
|
|
|
+}
|
|
|
+
|
|
|
+static int
|
|
|
+kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr)
|
|
|
{
|
|
|
unsigned long flags;
|
|
|
- TRAP_HANDLER_DECL;
|
|
|
+ int ret;
|
|
|
|
|
|
local_irq_save(flags);
|
|
|
- kgdb_handle_exception(vec >> 2, SIGTRAP, 0, regs);
|
|
|
+ ret = __kgdb_notify(ptr, cmd);
|
|
|
local_irq_restore(flags);
|
|
|
+
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
+static struct notifier_block kgdb_notifier = {
|
|
|
+ .notifier_call = kgdb_notify,
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Lowest-prio notifier priority, we want to be notified last:
|
|
|
+ */
|
|
|
+ .priority = -INT_MAX,
|
|
|
+};
|
|
|
+
|
|
|
int kgdb_arch_init(void)
|
|
|
{
|
|
|
- return 0;
|
|
|
+ return register_die_notifier(&kgdb_notifier);
|
|
|
}
|
|
|
|
|
|
void kgdb_arch_exit(void)
|
|
|
{
|
|
|
+ unregister_die_notifier(&kgdb_notifier);
|
|
|
}
|
|
|
|
|
|
struct kgdb_arch arch_kgdb_ops = {
|