Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 22648735 authored by Paul Mundt's avatar Paul Mundt
Browse files

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
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -13,7 +13,6 @@
#include <linux/linkage.h>

#if !defined(CONFIG_KGDB)
#define breakpoint_trap_handler		debug_trap_handler
#define singlestep_trap_handler		debug_trap_handler
#endif

+41 −5
Original line number Diff line number Diff line
/*
 * 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;
	}

	return NOTIFY_STOP;
}

BUILD_TRAP_HANDLER(breakpoint)
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 = {