The reset value of the BCR, BVR, WCR, and WVR registers are all UNKNOWN on ARMv7. Unfortunately, reset_ctrl_regs() clears these registers *after* enabling monitor mode, not before, and so some implementations may experience UNPREDICTABLE behavior if the reset values of these registers are non-zero. Clear the breakpoints before enabling monitor mode so that we don't experience boot hangs/loops due to breakpoints being enabled out of reset.
Signed-off-by: Stephen Boyd <sb...@codeaurora.org> --- arch/arm/kernel/hw_breakpoint.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index ba386bd..9eac571 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -216,6 +216,20 @@ static int get_num_brps(void) return core_has_mismatch_brps() ? brps - 1 : brps; } +/* Determine if halting mode is enabled */ +static int halting_mode_enabled(void) +{ + u32 dscr; + + ARM_DBG_READ(c1, 0, dscr); + + if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN, + "halting debug mode enabled. Unable to access hardware resources.\n")) { + return -EPERM; + } + return 0; +} + /* * In order to access the breakpoint/watchpoint control registers, * we must be running in debug monitor mode. Unfortunately, we can @@ -225,16 +239,13 @@ static int get_num_brps(void) static int enable_monitor_mode(void) { u32 dscr; - int ret = 0; + int ret; ARM_DBG_READ(c1, 0, dscr); /* Ensure that halting mode is disabled. */ - if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN, - "halting debug mode enabled. Unable to access hardware resources.\n")) { - ret = -EPERM; + if ((ret = halting_mode_enabled())) goto out; - } /* If monitor mode is already enabled, just return. */ if (dscr & ARM_DSCR_MDBGEN) @@ -935,7 +946,7 @@ static void reset_ctrl_regs(void *unused) isb(); reset_regs: - if (enable_monitor_mode()) + if (halting_mode_enabled()) return; /* We must also reset any reserved registers. */ @@ -949,6 +960,7 @@ reset_regs: write_wb_reg(ARM_BASE_WCR + i, 0UL); write_wb_reg(ARM_BASE_WVR + i, 0UL); } + enable_monitor_mode(); } static int __cpuinit dbg_reset_notify(struct notifier_block *self, -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/