This is an automated email from Gerrit. "Adrien Charruel <acharr...@nanoxplore.com>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/8654
-- gerrit commit 1c08b5d9ccd8a56737133574b9e4f5ef26340fe9 Author: Adrien Grassein <agrass...@nanoxplore.com> Date: Thu Jan 18 11:54:15 2024 +0100 target/aarch64: Handle better target clean up Clean up code never called restore function. The target was let with dirty registers values. Change-Id: I8cbba1fdae1d3c4a580197b7a97691443780ed06 Signed-off-by: Adrien Grassein <agrass...@nanoxplore.com> Signed-off-by: Adrien Charruel <acharr...@nanoxplore.com> diff --git a/src/target/aarch64.c b/src/target/aarch64.c index 9f122070aa..4a2b9df8a3 100644 --- a/src/target/aarch64.c +++ b/src/target/aarch64.c @@ -593,6 +593,7 @@ static int aarch64_restore_one(struct target *target, int current, uint64_t *address, int handle_breakpoints, int debug_execution) { struct armv8_common *armv8 = target_to_armv8(target); + struct aarch64_common *aarch64 = target_to_aarch64(target); struct arm *arm = &armv8->arm; int retval; uint64_t resume_pc; @@ -641,6 +642,8 @@ static int aarch64_restore_one(struct target *target, int current, if (retval == ERROR_OK) retval = aarch64_restore_context(target, handle_breakpoints); + aarch64->context_dirty = false; + return retval; } @@ -973,10 +976,13 @@ static int aarch64_debug_entry(struct target *target) { int retval = ERROR_OK; struct armv8_common *armv8 = target_to_armv8(target); + struct aarch64_common *aarch64 = target_to_aarch64(target); struct arm_dpm *dpm = &armv8->dpm; enum arm_state core_state; uint32_t dscr; + /* Mark the context as dirty this we will modify internal registers of the core. */ + aarch64->context_dirty = true; /* make sure to clear all sticky errors */ retval = mem_ap_write_atomic_u32(armv8->debug_ap, armv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE); @@ -2613,6 +2619,29 @@ static int aarch64_handle_target_request(void *priv) return ERROR_OK; } +static int aarch64_target_callback_event_handler(struct target *target, + enum target_event event, void *priv) +{ + int retval = ERROR_OK; + struct aarch64_common *aarch64 = target_to_aarch64(target); + /* Not used but mandatory for aarch64_restore_one because we can't pass a NULL pointer */ + uint64_t address; + + if (target != priv) + return ERROR_OK; + + switch (event) { + case TARGET_EVENT_GDB_DETACH: + if (aarch64->context_dirty) + retval = aarch64_restore_one(target, 1, &address, 0, 0); + break; + default: + break; + } + + return retval; +} + static int aarch64_examine_first(struct target *target) { struct aarch64_common *aarch64 = target_to_aarch64(target); @@ -2809,6 +2838,8 @@ static int aarch64_init_arch_info(struct target *target, target_register_timer_callback(aarch64_handle_target_request, 1, TARGET_TIMER_TYPE_PERIODIC, target); + target_register_event_callback(aarch64_target_callback_event_handler, target); + return ERROR_OK; } @@ -2855,6 +2886,13 @@ static void aarch64_deinit_target(struct target *target) struct aarch64_common *aarch64 = target_to_aarch64(target); struct armv8_common *armv8 = &aarch64->armv8_common; struct arm_dpm *dpm = &armv8->dpm; + uint64_t address; + + target_unregister_event_callback(aarch64_target_callback_event_handler, target); + + if (aarch64->context_dirty) + // Restore the previous state of the target (gp registers, MMU, caches, etc) + aarch64_restore_one(target, 1, &address, 0, 0); if (armv8->debug_ap) dap_put_ap(armv8->debug_ap); diff --git a/src/target/aarch64.h b/src/target/aarch64.h index b265e82498..1f570a2dda 100644 --- a/src/target/aarch64.h +++ b/src/target/aarch64.h @@ -58,6 +58,11 @@ struct aarch64_common { struct aarch64_brp *wp_list; enum aarch64_isrmasking_mode isrmasking_mode; + + /* Keep the fact that context (registers) of processor are dirty. + * This is used to correctly clean-up and restore the processor + * on exit. */ + bool context_dirty; }; static inline struct aarch64_common * --