Commit 22648735 authored by Paul Mundt's avatar Paul Mundt

sh: kgdb: Rework breakpoint handling on top of notifier chain.

This kills off kgdb's breakpoint handler and ties in to the notifier
chain instead.
Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent b74ab703
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
#include <linux/linkage.h> #include <linux/linkage.h>
#if !defined(CONFIG_KGDB) #if !defined(CONFIG_KGDB)
#define breakpoint_trap_handler debug_trap_handler
#define singlestep_trap_handler debug_trap_handler #define singlestep_trap_handler debug_trap_handler
#endif #endif
......
/* /*
* SuperH KGDB support * 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. * Single stepping taken from the old stub by Henry Bell and Jeremy Siegel.
* *
...@@ -251,24 +251,60 @@ BUILD_TRAP_HANDLER(singlestep) ...@@ -251,24 +251,60 @@ BUILD_TRAP_HANDLER(singlestep)
local_irq_restore(flags); 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;
}
return NOTIFY_STOP;
}
BUILD_TRAP_HANDLER(breakpoint) static int
kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr)
{ {
unsigned long flags; unsigned long flags;
TRAP_HANDLER_DECL; int ret;
local_irq_save(flags); local_irq_save(flags);
kgdb_handle_exception(vec >> 2, SIGTRAP, 0, regs); ret = __kgdb_notify(ptr, cmd);
local_irq_restore(flags); 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) int kgdb_arch_init(void)
{ {
return 0; return register_die_notifier(&kgdb_notifier);
} }
void kgdb_arch_exit(void) void kgdb_arch_exit(void)
{ {
unregister_die_notifier(&kgdb_notifier);
} }
struct kgdb_arch arch_kgdb_ops = { struct kgdb_arch arch_kgdb_ops = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment