This is an automated email from Gerrit. "Tomas Vanek <[email protected]>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9589
-- gerrit commit 0fe07010ec2f5c1c358e75f2f7d6e69efb33cd4f Author: Tomas Vanek <[email protected]> Date: Sun Nov 30 12:09:47 2025 +0100 target/riscv: make memory bus read faster Prepare up to 256 memory reads in a single batch. Change-Id: Ic27e54418f98c48c5cffedfb77ad2d20a540bb6c Signed-off-by: Tomas Vanek <[email protected]> diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 50e0f83dd8..22128d7ab7 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -3375,9 +3375,6 @@ static int read_memory_bus_v1(struct target *target, const struct riscv_mem_acce target_addr_t next_address = address; target_addr_t end_address = address + (increment ? count : 1) * size; - /* TODO: Reading all the elements in a single batch will boost the - * performance. - */ while (next_address < end_address) { uint32_t sbcs_write = set_field(0, DM_SBCS_SBREADONADDR, 1); sbcs_write |= sb_sbaccess(size); @@ -3402,17 +3399,20 @@ static int read_memory_bus_v1(struct target *target, const struct riscv_mem_acce * be unnecessary. */ uint32_t sbvalue[4] = {0}; - for (uint32_t i = (next_address - address) / size; i < count - 1; i++) { + for (uint32_t i = (next_address - address) / size; i < count - 1;) { const uint32_t size_in_words = DIV_ROUND_UP(size, 4); - struct riscv_batch *batch = riscv_batch_alloc(target, size_in_words); + const uint32_t chunk = MIN(256 / size_in_words, (count - 1 - i)); + struct riscv_batch *batch = riscv_batch_alloc(target, chunk * size_in_words); /* Read of sbdata0 must be performed as last because it * starts the new bus data transfer * (in case "sbcs.sbreadondata" was set above). * We don't want to start the next bus read before we * fetch all the data from the last bus read. */ - for (uint32_t j = size_in_words - 1; j > 0; --j) - riscv_batch_add_dm_read(batch, sbdata[j], RISCV_DELAY_BASE); - riscv_batch_add_dm_read(batch, sbdata[0], RISCV_DELAY_SYSBUS_READ); + for (uint32_t m = 0; m < chunk; m++) { + for (uint32_t j = size_in_words - 1; j > 0; --j) + riscv_batch_add_dm_read(batch, sbdata[j], RISCV_DELAY_BASE); + riscv_batch_add_dm_read(batch, sbdata[0], RISCV_DELAY_SYSBUS_READ); + } int res = batch_run_timeout(target, batch); if (res != ERROR_OK) { @@ -3421,14 +3421,19 @@ static int read_memory_bus_v1(struct target *target, const struct riscv_mem_acce } const size_t last_key = batch->read_keys_used - 1; - for (size_t k = 0; k <= last_key; ++k) { - sbvalue[k] = riscv_batch_get_dmi_read_data(batch, last_key - k); - buf_set_u32(buffer + i * size + k * 4, 0, MIN(32, 8 * size), sbvalue[k]); + size_t k = 0; + for (uint32_t m = 0; k <= last_key && m < chunk; m++) { + for (int j = size_in_words - 1; j >= 0; j--) { + uint32_t d = riscv_batch_get_dmi_read_data(batch, k); + buf_set_u32(buffer + (i + m) * size + j * 4, 0, MIN(32, 8 * size), d); + sbvalue[j] = d; + k++; + } + const target_addr_t read_addr = address + (i + m) * increment; + log_memory_access(read_addr, sbvalue, size, true); } - riscv_batch_free(batch); - const target_addr_t read_addr = address + i * increment; - log_memory_access(read_addr, sbvalue, size, true); + i += chunk; } uint32_t sbcs_read = 0; --
