|
From: openocd-gerrit <ope...@us...> - 2025-11-30 10:22:37
|
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 eef37df3aaeab98ac8df4ad6447680228d2a9772 (commit)
from 37dcf4359bd22025aaa809a8559b129ed6607195 (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 eef37df3aaeab98ac8df4ad6447680228d2a9772
Author: Antonio Borneo <bor...@gm...>
Date: Wed Nov 5 14:45:29 2025 +0100
target: cortex-m: defer cache identification on Cortex-M7 under reset
On Cortex-M7 only, several registers in System Control Space (SCS)
are not accessible when the CPU is under reset, generating a bus
error.
This causes OpenOCD to fail examining the CPU when the board reset
button is pressed or when the flag 'connect_assert_srst' is used
on 'reset_config' command.
Introduce a deferred identification of the cache and run it during
polling and at target halted (just in case of polling disabled).
Change-Id: Ia5c582ae95f825c5fb8c2dcfb320142f7ac04a9f
Signed-off-by: Antonio Borneo <bor...@gm...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9232
Reviewed-by: Tomas Vanek <va...@fb...>
Tested-by: jenkins
diff --git a/src/target/armv7m_cache.c b/src/target/armv7m_cache.c
index cc0c9d140..f07ac142f 100644
--- a/src/target/armv7m_cache.c
+++ b/src/target/armv7m_cache.c
@@ -68,7 +68,7 @@ static struct armv7m_cache_size decode_ccsidr(uint32_t ccsidr)
return size;
}
-int armv7m_identify_cache(struct target *target)
+static int armv7m_identify_cache_internal(struct target *target)
{
struct armv7m_common *armv7m = target_to_armv7m(target);
struct armv7m_cache_common *cache = &armv7m->armv7m_cache;
@@ -191,6 +191,54 @@ int armv7m_identify_cache(struct target *target)
return ERROR_OK;
}
+/*
+ * On Cortex-M7 only, when the CPU is kept in reset, several registers of the
+ * System Control Space (SCS) are not accessible and return bus error.
+ * The list of accessible registers is:
+ * - 0xE000ED00
+ * - 0xE000ED30
+ * - 0xE000EDF0 ... 0xE000EEFC
+ * - 0xE000EF40 ... 0xE000EF48
+ * - 0xE000EFD0 ... 0xE000EFFC
+ * This makes impossible detecting the cache during the reset.
+ * Use a deferred mechanism to detect the cache during polling or when the
+ * Cortex-M7 halts.
+ */
+int armv7m_identify_cache(struct target *target)
+{
+ struct cortex_m_common *cortex_m = target_to_cm(target);
+ struct armv7m_common *armv7m = target_to_armv7m(target);
+ struct armv7m_cache_common *cache = &armv7m->armv7m_cache;
+
+ if (cache->info_valid)
+ return ERROR_OK;
+
+ if (cortex_m->core_info->impl_part == CORTEX_M7_PARTNO
+ && cortex_m->dcb_dhcsr & S_RESET_ST) {
+ cache->defer_identification = true;
+ return ERROR_OK;
+ }
+
+ return armv7m_identify_cache_internal(target);
+}
+
+int armv7m_deferred_identify_cache(struct target *target)
+{
+ struct armv7m_common *armv7m = target_to_armv7m(target);
+ struct armv7m_cache_common *cache = &armv7m->armv7m_cache;
+
+ if (cache->info_valid || !cache->defer_identification)
+ return ERROR_OK;
+
+ int retval = armv7m_identify_cache_internal(target);
+ if (retval != ERROR_OK)
+ return retval;
+
+ cache->defer_identification = false;
+
+ return ERROR_OK;
+}
+
int armv7m_d_cache_flush(struct target *target, uint32_t address,
unsigned int length)
{
@@ -250,6 +298,11 @@ int armv7m_handle_cache_info_command(struct command_invocation *cmd,
return ERROR_FAIL;
}
+ if (cache->defer_identification) {
+ command_print(cmd, "Cache not detected yet");
+ return ERROR_OK;
+ }
+
if (!cache->info_valid) {
command_print(cmd, "No cache detected");
return ERROR_OK;
diff --git a/src/target/armv7m_cache.h b/src/target/armv7m_cache.h
index 576bff8d6..e6d943209 100644
--- a/src/target/armv7m_cache.h
+++ b/src/target/armv7m_cache.h
@@ -38,6 +38,7 @@ struct armv7m_arch_cache {
// common cache information
struct armv7m_cache_common {
bool info_valid;
+ bool defer_identification;
bool has_i_cache;
bool has_d_u_cache;
unsigned int loc; // level of coherency
@@ -47,6 +48,7 @@ struct armv7m_cache_common {
};
int armv7m_identify_cache(struct target *target);
+int armv7m_deferred_identify_cache(struct target *target);
int armv7m_d_cache_flush(struct target *target, uint32_t address,
unsigned int length);
int armv7m_i_cache_inval(struct target *target, uint32_t address,
diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c
index d15575bd7..ea94f1242 100644
--- a/src/target/cortex_m.c
+++ b/src/target/cortex_m.c
@@ -876,6 +876,10 @@ static int cortex_m_debug_entry(struct target *target)
}
// read caches state
+ retval = armv7m_deferred_identify_cache(target);
+ if (retval != ERROR_OK)
+ return retval;
+
uint32_t ccr = 0;
if (armv7m->armv7m_cache.info_valid) {
retval = mem_ap_read_u32(armv7m->debug_ap, CCR, &ccr);
@@ -1018,6 +1022,10 @@ static int cortex_m_poll_one(struct target *target)
/* S_RESET_ST was expected (in a reset command). Continue processing
* to quickly get out of TARGET_RESET state */
+ } else {
+ retval = armv7m_deferred_identify_cache(target);
+ if (retval != ERROR_OK)
+ return retval;
}
if (target->state == TARGET_RESET) {
@@ -2952,6 +2960,18 @@ int cortex_m_examine(struct target *target)
if (retval != ERROR_OK)
return retval;
+ /*
+ * Use a safe value of sticky S_RESET_ST for cache detection, before
+ * clearing it below.
+ */
+ if (!armv7m->is_hla_target) {
+ retval = armv7m_identify_cache(target);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Cannot detect cache");
+ return retval;
+ }
+ }
+
/* Don't cumulate sticky S_RESET_ST at the very first read of DHCSR
* as S_RESET_ST may indicate a reset that happened long time ago
* (most probably the power-on reset before OpenOCD was started).
@@ -3021,14 +3041,6 @@ int cortex_m_examine(struct target *target)
LOG_TARGET_INFO(target, "target has %d breakpoints, %d watchpoints",
cortex_m->fp_num_code,
cortex_m->dwt_num_comp);
-
- if (!armv7m->is_hla_target) {
- retval = armv7m_identify_cache(target);
- if (retval != ERROR_OK) {
- LOG_ERROR("Cannot detect cache");
- return retval;
- }
- }
}
return ERROR_OK;
-----------------------------------------------------------------------
Summary of changes:
src/target/armv7m_cache.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++-
src/target/armv7m_cache.h | 2 ++
src/target/cortex_m.c | 28 +++++++++++++++++-------
3 files changed, 76 insertions(+), 9 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|