From: OpenOCD-Gerrit <ope...@us...> - 2021-03-19 21:58:40
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 6c0151623cb09da6a80655cedf568db927ae2d93 (commit) from 25218e8935037367e419219f8c855d92a3163023 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6c0151623cb09da6a80655cedf568db927ae2d93 Author: Christian Hoff <chr...@ad...> Date: Mon Nov 23 14:34:56 2020 +0100 aarch64: add support for "reset halt" Support halting the CPU directly after a reset. If halt is requested, the CPU stops directly at the reset vector, before any code is executed. This functionality was implemented using the Reset Catch debug event. Change-Id: If90d54c088442340376f0b588ba10267ea8e7327 Signed-off-by: Christian Hoff <chr...@ad...> Reviewed-on: http://openocd.zylin.com/5947 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> Reviewed-by: Tarek BOCHKATI <tar...@gm...> diff --git a/src/target/aarch64.c b/src/target/aarch64.c index d111a0568..e45803040 100644 --- a/src/target/aarch64.c +++ b/src/target/aarch64.c @@ -1677,22 +1677,102 @@ static int aarch64_remove_breakpoint(struct target *target, struct breakpoint *b * Cortex-A8 Reset functions */ +static int aarch64_enable_reset_catch(struct target *target, bool enable) +{ + struct armv8_common *armv8 = target_to_armv8(target); + uint32_t edecr; + int retval; + + retval = mem_ap_read_atomic_u32(armv8->debug_ap, + armv8->debug_base + CPUV8_DBG_EDECR, &edecr); + LOG_DEBUG("EDECR = 0x%08" PRIx32 ", enable=%d", edecr, enable); + if (retval != ERROR_OK) + return retval; + + if (enable) + edecr |= ECR_RCE; + else + edecr &= ~ECR_RCE; + + return mem_ap_write_atomic_u32(armv8->debug_ap, + armv8->debug_base + CPUV8_DBG_EDECR, edecr); +} + +static int aarch64_clear_reset_catch(struct target *target) +{ + struct armv8_common *armv8 = target_to_armv8(target); + uint32_t edesr; + int retval; + bool was_triggered; + + /* check if Reset Catch debug event triggered as expected */ + retval = mem_ap_read_atomic_u32(armv8->debug_ap, + armv8->debug_base + CPUV8_DBG_EDESR, &edesr); + if (retval != ERROR_OK) + return retval; + + was_triggered = !!(edesr & ESR_RC); + LOG_DEBUG("Reset Catch debug event %s", + was_triggered ? "triggered" : "NOT triggered!"); + + if (was_triggered) { + /* clear pending Reset Catch debug event */ + edesr &= ~ESR_RC; + retval = mem_ap_write_atomic_u32(armv8->debug_ap, + armv8->debug_base + CPUV8_DBG_EDESR, edesr); + if (retval != ERROR_OK) + return retval; + } + + return ERROR_OK; +} + static int aarch64_assert_reset(struct target *target) { struct armv8_common *armv8 = target_to_armv8(target); + enum reset_types reset_config = jtag_get_reset_config(); + int retval; LOG_DEBUG(" "); - /* FIXME when halt is requested, make it work somehow... */ - /* Issue some kind of warm reset. */ if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT)) target_handle_event(target, TARGET_EVENT_RESET_ASSERT); - else if (jtag_get_reset_config() & RESET_HAS_SRST) { + else if (reset_config & RESET_HAS_SRST) { + bool srst_asserted = false; + + if (target->reset_halt) { + if (target_was_examined(target)) { + + if (reset_config & RESET_SRST_NO_GATING) { + /* + * SRST needs to be asserted *before* Reset Catch + * debug event can be set up. + */ + adapter_assert_reset(); + srst_asserted = true; + + /* make sure to clear all sticky errors */ + mem_ap_write_atomic_u32(armv8->debug_ap, + armv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE); + } + + /* set up Reset Catch debug event to halt the CPU after reset */ + retval = aarch64_enable_reset_catch(target, true); + if (retval != ERROR_OK) + LOG_WARNING("%s: Error enabling Reset Catch debug event; the CPU will not halt immediately after reset!", + target_name(target)); + } else { + LOG_WARNING("%s: Target not examined, will not halt immediately after reset!", + target_name(target)); + } + } + /* REVISIT handle "pulls" cases, if there's * hardware that needs them to work. */ - adapter_assert_reset(); + if (!srst_asserted) + adapter_assert_reset(); } else { LOG_ERROR("%s: how to reset?", target_name(target)); return ERROR_FAIL; @@ -1721,23 +1801,37 @@ static int aarch64_deassert_reset(struct target *target) if (!target_was_examined(target)) return ERROR_OK; - retval = aarch64_poll(target); + retval = aarch64_init_debug_access(target); if (retval != ERROR_OK) return retval; - retval = aarch64_init_debug_access(target); + retval = aarch64_poll(target); if (retval != ERROR_OK) return retval; if (target->reset_halt) { + /* clear pending Reset Catch debug event */ + retval = aarch64_clear_reset_catch(target); + if (retval != ERROR_OK) + LOG_WARNING("%s: Clearing Reset Catch debug event failed", + target_name(target)); + + /* disable Reset Catch debug event */ + retval = aarch64_enable_reset_catch(target, false); + if (retval != ERROR_OK) + LOG_WARNING("%s: Disabling Reset Catch debug event failed", + target_name(target)); + if (target->state != TARGET_HALTED) { LOG_WARNING("%s: ran after reset and before halt ...", target_name(target)); retval = target_halt(target); + if (retval != ERROR_OK) + return retval; } } - return retval; + return ERROR_OK; } static int aarch64_write_cpu_memory_slow(struct target *target, diff --git a/src/target/armv8_dpm.h b/src/target/armv8_dpm.h index ee6f699de..a6cade345 100644 --- a/src/target/armv8_dpm.h +++ b/src/target/armv8_dpm.h @@ -16,6 +16,7 @@ #define OPENOCD_TARGET_ARMV8_DPM_H #include "arm_dpm.h" +#include "helper/bits.h" /* forward-declare struct armv8_common */ struct armv8_common; @@ -96,6 +97,12 @@ void armv8_dpm_report_wfar(struct arm_dpm *dpm, uint64_t wfar); #define DRCR_RESTART (1 << 1) #define DRCR_CLEAR_EXCEPTIONS (1 << 2) +/* ECR (Execution Control Register) bits */ +#define ECR_RCE BIT(1) + +/* ESR (Event Status Register) bits */ +#define ESR_RC BIT(1) + /* PRSR (processor debug status register) bits */ #define PRSR_PU (1 << 0) #define PRSR_SPD (1 << 1) ----------------------------------------------------------------------- Summary of changes: src/target/aarch64.c | 108 +++++++++++++++++++++++++++++++++++++++++++++---- src/target/armv8_dpm.h | 7 ++++ 2 files changed, 108 insertions(+), 7 deletions(-) hooks/post-receive -- Main OpenOCD repository |