This is an automated email from Gerrit. "Marek Vrbka <marek.vr...@codasip.com>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/8070
-- gerrit commit 4cf97e51ccf06ebd3279ceb3d51428242ae16dbb Author: Marek Vrbka <marek.vr...@codasip.com> Date: Fri Jan 12 14:38:56 2024 +0100 target: Introduce flush_reg_cache command This patch introduces the flush_reg_cache command, as well as the callback flush_reg_cache for targets to implement. Said command forces a flush of the register cache and invalidates it if the flag -invalidate is set. This command is useful for testing purposes, we plan to implement it for the RISC-V target. Change-Id: I9537a5f05b46330f70aad17f77b2b80dedad068a Signed-off-by: Marek Vrbka <marek.vr...@codasip.com> diff --git a/doc/openocd.texi b/doc/openocd.texi index 53730eafaf..b0da08e806 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -9128,6 +9128,11 @@ get_reg @{pc sp@} @end example @end deffn +@deffn {Command} {flush_reg_cache} [-invalidate] +Flush the internal OpenOCD's register cache - write back the dirty register values to the target. +If -invalidate is set, also invalidate (forget) the OpenOCD's cached register values; therefore the next +call to get_reg is guaranteed to read the fresh register value directly from the target. + @deffn {Command} {write_memory} address width data ['phys'] This function provides an efficient way to write to the target memory from a Tcl script. diff --git a/src/target/target.c b/src/target/target.c index 61890aa3e5..ca49474da6 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -1468,6 +1468,16 @@ unsigned int target_data_bits(struct target *target) return 32; } +int target_flush_reg_cache(struct target *target, bool invalidate) +{ + if (target->type->flush_reg_cache == NULL) { + LOG_TARGET_ERROR(target, "Register cache flushing not implemented for this target."); + return ERROR_NOT_IMPLEMENTED; + } + + return target->type->flush_reg_cache(target, invalidate); +} + static int target_profiling(struct target *target, uint32_t *samples, uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds) { @@ -6919,6 +6929,27 @@ nextw: return retval; } +COMMAND_HANDLER(handle_flush_reg_cache_command) +{ + struct target *target = get_current_target(CMD_CTX); + + if (CMD_ARGC > 1) + return ERROR_COMMAND_SYNTAX_ERROR; + + bool invalidate = false; + + if (CMD_ARGC == 1) { + if (!strcmp(CMD_ARGV[0], "-invalidate")) { + invalidate = true; + } else { + LOG_TARGET_ERROR(target, "Invalid flush_reg_cache option: %s", CMD_ARGV[0]); + return ERROR_COMMAND_SYNTAX_ERROR; + } + } + + return target_flush_reg_cache(target, invalidate); +} + static const struct command_registration target_exec_command_handlers[] = { { .name = "fast_load_image", @@ -7132,7 +7163,7 @@ static const struct command_registration target_exec_command_handlers[] = { .mode = COMMAND_EXEC, .jim_handler = target_jim_get_reg, .help = "Get register values from the target", - .usage = "list", + .usage = "['-force'] list", }, { .name = "set_reg", @@ -7177,7 +7208,13 @@ static const struct command_registration target_exec_command_handlers[] = { .help = "Test the target's memory access functions", .usage = "size", }, - + { + .name = "flush_reg_cache", + .handler = handle_flush_reg_cache_command, + .mode = COMMAND_EXEC, + .help = "Flush register cache", + .usage = "['-invalidate']", + }, COMMAND_REGISTRATION_DONE }; static int target_register_user_commands(struct command_context *cmd_ctx) diff --git a/src/target/target.h b/src/target/target.h index f69ee77ac4..04f86439df 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -693,6 +693,13 @@ unsigned target_address_bits(struct target *target); */ unsigned int target_data_bits(struct target *target); +/** + * Flush the register cache. + * + * If invalidate == true, also invalidate the cache. + */ +int target_flush_reg_cache(struct target *target, bool invalidate); + /** Return the *name* of this targets current state */ const char *target_state_name(struct target *target); diff --git a/src/target/target_type.h b/src/target/target_type.h index 678ce0f466..a9eb9e7c57 100644 --- a/src/target/target_type.h +++ b/src/target/target_type.h @@ -309,6 +309,10 @@ struct target_type { * will typically be 32 for 32-bit targets, and 64 for 64-bit targets. If * not implemented, it's assumed to be 32. */ unsigned int (*data_bits)(struct target *target); + + /* Flushes register cache. + * If invalidate is set to true, also invalidate the cache. */ + int (*flush_reg_cache)(struct target *target, bool invalidate); }; extern struct target_type aarch64_target; --