[prev in list] [next in list] [prev in thread] [next in thread]
List: openocd-development
Subject: [PATCH]: d6f647fb48 Create the `riscv repeat_read` command
From: gerrit () openocd ! org
Date: 2024-05-09 16:49:13
Message-ID: 20240509164913.29942D7 () openocd ! org
[Download RAW message or body]
This is an automated email from Gerrit.
"Bernhard Rosenkraenzer <bero@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 <bero@baylibre.com>
Date: Thu May 9 16:07:47 2024 +0200
Create the `riscv repeat_read` command
This is based on Tim Newsome <tim@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 <tim@sifive.com>
Signed-off-by: Bernhard Rosenkränzer <bero@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);
--
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic