mirror of https://gitee.com/openkylin/linux.git
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: Dietmar Eggemann <dietmar.eggemann@arm.com> [will: removed redundant has_ossr check] Signed-off-by: Will Deacon <will.deacon@arm.com>
This commit is contained in:
parent
57ba899731
commit
9a6eb310ea
|
@ -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 = {
|
||||||
.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)
|
||||||
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);
|
||||||
|
|
Loading…
Reference in New Issue