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;

-- 

Reply via email to