This function is only called twice, once for each of breakpoint and watchpoint. Hoist the separate bp/wp code into the respective callers.
Signed-off-by: Richard Henderson <[email protected]> --- target/arm/tcg/debug.c | 49 +++++++++++++++++------------------------- 1 file changed, 20 insertions(+), 29 deletions(-) diff --git a/target/arm/tcg/debug.c b/target/arm/tcg/debug.c index 306106b7e8..519a06fbc7 100644 --- a/target/arm/tcg/debug.c +++ b/target/arm/tcg/debug.c @@ -252,41 +252,16 @@ static bool linked_bp_matches(ARMCPU *cpu, int lbn) return contextidr == (uint32_t)env->cp15.dbgbvr[lbn]; } -static bool bp_wp_matches(ARMCPU *cpu, int n, bool is_wp) +static bool bp_wp_matches(ARMCPU *cpu, uint64_t cr, int access_el) { CPUARMState *env = &cpu->env; - uint64_t cr; int pac, hmc, ssc, wt, lbn; /* * Note that for watchpoints the check is against the CPU security * state, not the S/NS attribute on the offending data access. */ bool is_secure = arm_is_secure(env); - int access_el = arm_current_el(env); - if (is_wp) { - CPUWatchpoint *wp = env->cpu_watchpoint[n]; - - if (!wp || !(wp->flags & BP_WATCHPOINT_HIT)) { - return false; - } - cr = env->cp15.dbgwcr[n]; - if (wp->hitattrs.user) { - /* - * The LDRT/STRT/LDT/STT "unprivileged access" instructions should - * match watchpoints as if they were accesses done at EL0, even if - * the CPU is at EL1 or higher. - */ - access_el = 0; - } - } else { - uint64_t pc = is_a64(env) ? env->pc : env->regs[15]; - - if (!env->cpu_breakpoint[n] || env->cpu_breakpoint[n]->pc != pc) { - return false; - } - cr = env->cp15.dbgbcr[n]; - } /* * The WATCHPOINT_HIT flag guarantees us that the watchpoint is * enabled and that the address and access type match; for breakpoints @@ -390,14 +365,16 @@ bool arm_debug_check_breakpoint(CPUState *cs, CPUBreakpoint *bp) */ for (n = 0; n < ARRAY_SIZE(env->cpu_breakpoint); n++) { - if (bp_wp_matches(cpu, n, false)) { + if (env->cpu_breakpoint[n] && + env->cpu_breakpoint[n]->pc != pc && + bp_wp_matches(cpu, env->cp15.dbgbcr[n], arm_current_el(env))) { return true; } } return false; } -bool arm_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp) +bool arm_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *ignore) { /* * Called by core code when a CPU watchpoint fires; need to check if this @@ -417,7 +394,21 @@ bool arm_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp) } for (n = 0; n < ARRAY_SIZE(env->cpu_watchpoint); n++) { - if (bp_wp_matches(cpu, n, true)) { + CPUWatchpoint *wp = env->cpu_watchpoint[n]; + int access_el; + + if (!wp || !(wp->flags & BP_WATCHPOINT_HIT)) { + continue; + } + + /* + * The LDRT/STRT/LDT/STT "unprivileged access" instructions should + * match watchpoints as if they were accesses done at EL0, even if + * the CPU is at EL1 or higher. + */ + access_el = (wp->hitattrs.user ? 0 : arm_current_el(env)); + + if (bp_wp_matches(cpu, env->cp15.dbgwcr[n], access_el)) { return true; } } -- 2.43.0
