This is an automated email from Gerrit.

"Bernhard Rosenkraenzer <b...@baylibre.com>" just uploaded a new patch set to 
Gerrit, which you can find at https://review.openocd.org/c/openocd/+/8259

-- gerrit

commit d6f647fb487f68de29832e8880872f22d08dea88
Author: Bernhard Rosenkränzer <b...@baylibre.com>
Date:   Thu May 9 16:07:47 2024 +0200

    Create the `riscv repeat_read` command
    
    This is based on Tim Newsome <t...@sifive.com>'s work on the
    openocd-riscv fork, merged into one commit and modified to
    work on top of current master.
    
    Change-Id: Ic1d750d329b2ab5136eb4b45d1f70f96ccac1b90
    Signed-off-by: Tim Newsome <t...@sifive.com>
    Signed-off-by: Bernhard Rosenkränzer <b...@baylibre.com>

diff --git a/doc/openocd.texi b/doc/openocd.texi
index 55e6e76808..f23618b721 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -11217,6 +11217,12 @@ encountering the target being busy. This command 
resets those learned values
 after `wait` scans. It's only useful for testing OpenOCD itself.
 @end deffn
 
+@deffn {Command} {riscv repeat_read} count address [size=4]
+Quickly read count words of the given size from address. This can be useful
+to read out a buffer that's memory-mapped to be accessed through a single
+address, or to sample a changing value in a memory-mapped device.
+@end deffn
+
 @deffn {Command} {riscv set_command_timeout_sec} [seconds]
 Set the wall-clock timeout (in seconds) for individual commands. The default
 should work fine for all but the slowest targets (eg. simulators).
diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c
index 720fb60a1b..1c4e154e5c 100644
--- a/src/flash/nor/tcl.c
+++ b/src/flash/nor/tcl.c
@@ -720,7 +720,8 @@ COMMAND_HANDLER(handle_flash_md_command)
 
        retval = flash_driver_read(bank, buffer, offset, sizebytes);
        if (retval == ERROR_OK)
-               target_handle_md_output(CMD, target, address, wordsize, count, 
buffer);
+               target_handle_md_output(CMD, target, address, wordsize, count,
+                               buffer, true);
 
        free(buffer);
 
diff --git a/src/target/dsp563xx.c b/src/target/dsp563xx.c
index 80cca1ed50..1e7180318a 100644
--- a/src/target/dsp563xx.c
+++ b/src/target/dsp563xx.c
@@ -2146,7 +2146,8 @@ COMMAND_HANDLER(dsp563xx_mem_command)
                err = dsp563xx_read_memory(target, mem_type, address, 
sizeof(uint32_t),
                                count, buffer);
                if (err == ERROR_OK)
-                       target_handle_md_output(CMD, target, address, 
sizeof(uint32_t), count, buffer);
+                       target_handle_md_output(CMD, target, address, 
sizeof(uint32_t),
+                               count, buffer, true);
 
        } else {
                b = buffer;
diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c
index 9cd4922d20..ac253566bc 100644
--- a/src/target/riscv/riscv.c
+++ b/src/target/riscv/riscv.c
@@ -2861,7 +2861,53 @@ COMMAND_HANDLER(handle_info)
        return 0;
 }
 
+COMMAND_HANDLER(handle_repeat_read)
+{
+       struct target *target = get_current_target(CMD_CTX);
+       RISCV_INFO(r);
+
+       if (CMD_ARGC < 2) {
+               LOG_ERROR("Command requires at least count and address 
arguments.");
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+       if (CMD_ARGC > 3) {
+               LOG_ERROR("Command takes at most 3 arguments.");
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+
+       uint32_t count;
+       COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], count);
+       target_addr_t address;
+       COMMAND_PARSE_ADDRESS(CMD_ARGV[1], address);
+       uint32_t size = 4;
+       if (CMD_ARGC > 2)
+               COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], size);
+
+       if (count == 0)
+               return ERROR_OK;
+
+       uint8_t *buffer = malloc(size * count);
+       if (!buffer) {
+               LOG_ERROR("malloc failed");
+               return ERROR_FAIL;
+       }
+       int result = r->read_memory(target, address, size, count, buffer, 0);
+       if (result == ERROR_OK) {
+               target_handle_md_output(cmd, target, address, size, count, 
buffer,
+                       false);
+       }
+       free(buffer);
+       return result;
+}
+
 static const struct command_registration riscv_exec_command_handlers[] = {
+       {
+               .name = "repeat_read",
+               .handler = handle_repeat_read,
+               .mode = COMMAND_ANY,
+               .usage = "riscv repeat_read count address [size=4]",
+               .help = "Repeatedly read the value at address."
+       },
        {
                .name = "info",
                .handler = handle_info,
diff --git a/src/target/target.c b/src/target/target.c
index 5168305dee..9f8373c7a3 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -3338,7 +3338,7 @@ COMMAND_HANDLER(handle_step_command)
 
 void target_handle_md_output(struct command_invocation *cmd,
                struct target *target, target_addr_t address, unsigned size,
-               unsigned count, const uint8_t *buffer)
+               unsigned count, const uint8_t *buffer, bool include_address)
 {
        const unsigned line_bytecnt = 32;
        unsigned line_modulo = line_bytecnt / size;
@@ -3367,7 +3367,7 @@ void target_handle_md_output(struct command_invocation 
*cmd,
        }
 
        for (unsigned i = 0; i < count; i++) {
-               if (i % line_modulo == 0) {
+               if (include_address && (i % line_modulo == 0)) {
                        output_len += snprintf(output + output_len,
                                        sizeof(output) - output_len,
                                        TARGET_ADDR_FMT ": ",
@@ -3451,7 +3451,7 @@ COMMAND_HANDLER(handle_md_command)
        struct target *target = get_current_target(CMD_CTX);
        int retval = fn(target, address, size, count, buffer);
        if (retval == ERROR_OK)
-               target_handle_md_output(CMD, target, address, size, count, 
buffer);
+               target_handle_md_output(CMD, target, address, size, count, 
buffer, true);
 
        free(buffer);
 
diff --git a/src/target/target.h b/src/target/target.h
index d5c0e0e8c7..57dc2e5f37 100644
--- a/src/target/target.h
+++ b/src/target/target.h
@@ -779,7 +779,7 @@ void target_handle_event(struct target *t, enum 
target_event e);
 
 void target_handle_md_output(struct command_invocation *cmd,
        struct target *target, target_addr_t address, unsigned size,
-       unsigned count, const uint8_t *buffer);
+       unsigned count, const uint8_t *buffer, bool include_address);
 
 int target_profiling_default(struct target *target, uint32_t *samples, uint32_t
                max_num_samples, uint32_t *num_samples, uint32_t seconds);

-- 

Reply via email to