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;

-- 

Reply via email to