This is an automated email from Gerrit.

"Ciro Cattuto <[email protected]>" just uploaded a new patch set to 
Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9555

-- gerrit

commit 91330d3dfa0753cbc293be7cad2ea2d4679ef208
Author: Ciro Cattuto <[email protected]>
Date:   Fri Apr 3 17:06:42 2026 +0200

    target/riscv: fix stale cache after register write via Tcl 'reg' command
    
    riscv013_reg_set() and riscv011_reg_set() did not update the register's
    own cache entry (reg->value) after a successful write. As a result, the
    Tcl 'reg <name> <value>' command printed the stale pre-write value as
    confirmation rather than the value just written.
    
    For the 0.13 path, this is most visible with 'reg pc': writes to PC are
    redirected to DPC inside riscv_set_or_write_register(), which correctly
    updates the DPC cache entry but leaves the PC cache entry stale. The
    fix updates the PC cache entry explicitly after the write.
    
    For the 0.11 path, the same omission affects all registers.
    
    The hardware state was always written correctly; only the Tcl command
    output was misleading.
    
    Change-Id: I016a8e5344c5c957e994e343c8fef010c8c05b69
    Signed-off-by: Ciro Cattuto <[email protected]>

diff --git a/src/target/riscv/riscv-011_reg.c b/src/target/riscv/riscv-011_reg.c
index 9b72918c5c..352d995748 100644
--- a/src/target/riscv/riscv-011_reg.c
+++ b/src/target/riscv/riscv-011_reg.c
@@ -24,7 +24,13 @@ static int riscv011_reg_set(struct reg *reg, uint8_t *buf)
 {
        const riscv_reg_t value = buf_get_u64(buf, 0, reg->size);
        struct target * const target = riscv_reg_impl_get_target(reg);
-       return riscv011_set_register(target, reg->number, value);
+       int result = riscv011_set_register(target, reg->number, value);
+       if (result != ERROR_OK)
+               return result;
+       /* Update the cache entry so that the Tcl 'reg' command prints the
+        * value just written rather than the stale pre-write value. */
+       buf_set_u64(reg->value, 0, reg->size, value);
+       return ERROR_OK;
 }
 
 static const struct reg_arch_type *riscv011_gdb_regno_reg_type(uint32_t regno)
diff --git a/src/target/riscv/riscv-013_reg.c b/src/target/riscv/riscv-013_reg.c
index b2b1a921f2..9242d322f1 100644
--- a/src/target/riscv/riscv-013_reg.c
+++ b/src/target/riscv/riscv-013_reg.c
@@ -68,6 +68,12 @@ static int riscv013_reg_set(struct reg *reg, uint8_t *buf)
                const riscv_reg_t value = buf_get_u64(buf, 0, reg->size);
                if (riscv_reg_set(target, reg->number, value) != ERROR_OK)
                        return ERROR_FAIL;
+               /* Update this register's own cache entry so that the Tcl 'reg'
+                * command prints the value just written, not the stale 
pre-write
+                * value. Necessary because PC writes are redirected to DPC 
inside
+                * riscv_set_or_write_register(), which updates the DPC cache 
entry
+                * but leaves the PC cache entry stale. */
+               memcpy(reg->value, buf, DIV_ROUND_UP(reg->size, 8));
        }
 
        return ERROR_OK;

-- 

Reply via email to