From f14c4b5fb1e2509ad738afe491c099a84ca80749 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sun, 29 Jan 2012 05:28:21 +0400 Subject: target-xtensa: add DBREAK data breakpoints Add DBREAKA/DBREAKC SRs and implement DBREAK breakpoints as debug watchpoints. This implementation is not fully compliant to ISA: when a breakpoint is set to an unmapped/inaccessible memory address it generates TLB/memory protection exception instead of debug exception. See ISA, 4.7.7.3, 4.7.7.6 for more details. Signed-off-by: Max Filippov --- target-xtensa/helper.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'target-xtensa/helper.c') diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c index 0a26f8dd3a..2ef50d656e 100644 --- a/target-xtensa/helper.c +++ b/target-xtensa/helper.c @@ -58,9 +58,44 @@ void xtensa_register_core(XtensaConfigList *node) xtensa_cores = node; } +static uint32_t check_hw_breakpoints(CPUState *env) +{ + unsigned i; + + for (i = 0; i < env->config->ndbreak; ++i) { + if (env->cpu_watchpoint[i] && + env->cpu_watchpoint[i]->flags & BP_WATCHPOINT_HIT) { + return DEBUGCAUSE_DB | (i << DEBUGCAUSE_DBNUM_SHIFT); + } + } + return 0; +} + +static CPUDebugExcpHandler *prev_debug_excp_handler; + +static void breakpoint_handler(CPUState *env) +{ + if (env->watchpoint_hit) { + if (env->watchpoint_hit->flags & BP_CPU) { + uint32_t cause; + + env->watchpoint_hit = NULL; + cause = check_hw_breakpoints(env); + if (cause) { + debug_exception_env(env, cause); + } + cpu_resume_from_signal(env, NULL); + } + } + if (prev_debug_excp_handler) { + prev_debug_excp_handler(env); + } +} + CPUXtensaState *cpu_xtensa_init(const char *cpu_model) { static int tcg_inited; + static int debug_handler_inited; CPUXtensaState *env; const XtensaConfig *config = NULL; XtensaConfigList *core = xtensa_cores; @@ -84,6 +119,12 @@ CPUXtensaState *cpu_xtensa_init(const char *cpu_model) xtensa_translate_init(); } + if (!debug_handler_inited && tcg_enabled()) { + debug_handler_inited = 1; + prev_debug_excp_handler = + cpu_set_debug_excp_handler(breakpoint_handler); + } + xtensa_irq_init(env); qemu_init_vcpu(env); return env; -- cgit v1.2.1