Commit 9a6eb310 authored by Dietmar Eggemann's avatar Dietmar Eggemann Committed by Will Deacon

ARM: hw_breakpoint: Debug powerdown support for self-hosted debug

This patch introduces debug powerdown support for self-hosted debug for v7
and v7.1 debug architecture for a SinglePower system, i.e. a system without a
separate core and debug power domain. On a SinglePower system the OS Lock is
lost over a powerdown.

If CONFIG_CPU_PM is set the new function pm_init() registers hw_breakpoint
with CPU PM for a system supporting OS Save and Restore.

Receiving a CPU PM EXIT notifier indicates that a single CPU has exited a low
power state. A call to reset_ctrl_regs() is hooked into the CPU PM EXIT
notifier chain. This function makes sure that the sticky power-down is clear
(only v7 debug), the OS Double Lock is clear (only v7.1 debug) and it clears
the OS Lock for v7 debug (for a system supporting OS Save and Restore) and
v7.1 debug. Furthermore, it clears any vector-catch events and all
breakpoint/watchpoint control/value registers for v7 and v7.1 debug.
Signed-off-by: default avatarDietmar Eggemann <dietmar.eggemann@arm.com>
[will: removed redundant has_ossr check]
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
parent 57ba8997
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/perf_event.h> #include <linux/perf_event.h>
#include <linux/hw_breakpoint.h> #include <linux/hw_breakpoint.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/cpu_pm.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/cputype.h> #include <asm/cputype.h>
...@@ -1032,6 +1033,30 @@ static struct notifier_block __cpuinitdata dbg_reset_nb = { ...@@ -1032,6 +1033,30 @@ static struct notifier_block __cpuinitdata dbg_reset_nb = {
.notifier_call = dbg_reset_notify, .notifier_call = dbg_reset_notify,
}; };
#ifdef CONFIG_CPU_PM
static int dbg_cpu_pm_notify(struct notifier_block *self, unsigned long action,
void *v)
{
if (action == CPU_PM_EXIT)
reset_ctrl_regs(NULL);
return NOTIFY_OK;
}
static struct notifier_block __cpuinitdata dbg_cpu_pm_nb = {
.notifier_call = dbg_cpu_pm_notify,
};
static void __init pm_init(void)
{
cpu_pm_register_notifier(&dbg_cpu_pm_nb);
}
#else
static inline void pm_init(void)
{
}
#endif
static int __init arch_hw_breakpoint_init(void) static int __init arch_hw_breakpoint_init(void)
{ {
debug_arch = get_debug_arch(); debug_arch = get_debug_arch();
...@@ -1081,8 +1106,9 @@ static int __init arch_hw_breakpoint_init(void) ...@@ -1081,8 +1106,9 @@ static int __init arch_hw_breakpoint_init(void)
hook_ifault_code(FAULT_CODE_DEBUG, hw_breakpoint_pending, SIGTRAP, hook_ifault_code(FAULT_CODE_DEBUG, hw_breakpoint_pending, SIGTRAP,
TRAP_HWBKPT, "breakpoint debug exception"); TRAP_HWBKPT, "breakpoint debug exception");
/* Register hotplug notifier. */ /* Register hotplug and PM notifiers. */
register_cpu_notifier(&dbg_reset_nb); register_cpu_notifier(&dbg_reset_nb);
pm_init();
return 0; return 0;
} }
arch_initcall(arch_hw_breakpoint_init); arch_initcall(arch_hw_breakpoint_init);
......
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