summaryrefslogtreecommitdiff
path: root/arch/arm/kernel/hw_breakpoint.c
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2011-02-11 15:55:12 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-02-11 22:54:47 +0000
commited19b739c5c76ad241d30f6c6a5ee96fb284f4cf (patch)
tree5e36a488dbf997875b732faff8fabfdbe1fac070 /arch/arm/kernel/hw_breakpoint.c
parent34cd2d38db423a991a36d14e9f79e98993addd07 (diff)
ARM: 6656/1: hw_breakpoint: avoid UNPREDICTABLE behaviour when reading DBGDSCR
Reading baseline CP14 registers, other than DBGDIDR, when the OS Lock is set leads to UNPREDICTABLE behaviour. This patch ensures that we clear the OS lock before accessing anything other than the DBGDIDR, thereby avoiding this behaviour. Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel/hw_breakpoint.c')
-rw-r--r--arch/arm/kernel/hw_breakpoint.c26
1 files changed, 13 insertions, 13 deletions
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
index c9f3f0467570..ab02d8aadb77 100644
--- a/arch/arm/kernel/hw_breakpoint.c
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -834,11 +834,11 @@ static void reset_ctrl_regs(void *unused)
/*
* v7 debug contains save and restore registers so that debug state
- * can be maintained across low-power modes without leaving
- * the debug logic powered up. It is IMPLEMENTATION DEFINED whether
- * we can write to the debug registers out of reset, so we must
- * unlock the OS Lock Access Register to avoid taking undefined
- * instruction exceptions later on.
+ * can be maintained across low-power modes without leaving the debug
+ * logic powered up. It is IMPLEMENTATION DEFINED whether we can access
+ * the debug registers out of reset, so we must unlock the OS Lock
+ * Access Register to avoid taking undefined instruction exceptions
+ * later on.
*/
if (debug_arch >= ARM_DEBUG_ARCH_V7_ECP14) {
/*
@@ -899,18 +899,18 @@ static int __init arch_hw_breakpoint_init(void)
pr_info("%d breakpoint(s) reserved for watchpoint "
"single-step.\n", core_num_reserved_brps);
+ /*
+ * Reset the breakpoint resources. We assume that a halting
+ * debugger will leave the world in a nice state for us.
+ */
+ on_each_cpu(reset_ctrl_regs, NULL, 1);
+
ARM_DBG_READ(c1, 0, dscr);
if (dscr & ARM_DSCR_HDBGEN) {
+ max_watchpoint_len = 4;
pr_warning("halting debug mode enabled. Assuming maximum "
- "watchpoint size of 4 bytes.");
+ "watchpoint size of %u bytes.", max_watchpoint_len);
} else {
- /*
- * Reset the breakpoint resources. We assume that a halting
- * debugger will leave the world in a nice state for us.
- */
- smp_call_function(reset_ctrl_regs, NULL, 1);
- reset_ctrl_regs(NULL);
-
/* Work out the maximum supported watchpoint length. */
max_watchpoint_len = get_max_wp_len();
pr_info("maximum watchpoint size is %u bytes.\n",