This is an automated email from Gerrit.

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

-- gerrit

commit c1d8ff3022aabf969d23538f8938a0e96fe2698f
Author: Evgeniy Naydanov <[email protected]>
Date:   Tue Oct 28 17:16:55 2025 +0300

    target/riscv: fix progbuf memory writes in case last write is busy
    
    Restarting the program buffer memory write pipeline when the write of
    the last element resulted in the busy response triggers an extra memory
    wrtite, that is cought by an assertion:
    ```
    src/target/riscv/riscv-013.c:5048: write_memory_progbuf_inner: Assertion
    `next_addr_on_target - args.address <= (target_addr_t)args.size *
    args.count' failed.
    ```
    
    Change-Id: I0f27145cad24686cf539aebfea7f6578b7cd78ab
    Signed-off-by: Evgeniy Naydanov <[email protected]>

diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c
index 370a15607e..6fa5e025be 100644
--- a/src/target/riscv/riscv-013.c
+++ b/src/target/riscv/riscv-013.c
@@ -4875,7 +4875,8 @@ static int write_memory_progbuf_teardown(struct target 
*target)
  * failed write.
  */
 static int write_memory_progbuf_handle_busy(struct target *target,
-               target_addr_t *address_p, uint32_t size, const uint8_t *buffer)
+               target_addr_t *address_p, target_addr_t end_address, uint32_t 
size,
+               const uint8_t *buffer)
 {
        int res = riscv013_clear_abstract_error(target);
        if (res != ERROR_OK)
@@ -4891,8 +4892,12 @@ static int write_memory_progbuf_handle_busy(struct 
target *target,
        if (register_read_direct(target, &address_on_target, GDB_REGNO_S0) != 
ERROR_OK)
                return ERROR_FAIL;
        const uint8_t * const curr_buff = buffer + (address_on_target - 
*address_p);
-       LOG_TARGET_DEBUG(target, "Restarting from 0x%" TARGET_PRIxADDR, 
*address_p);
        *address_p = address_on_target;
+       if (*address_p == end_address) {
+               LOG_TARGET_DEBUG(target, "Got busy while reading after reading 
the last element");
+               return ERROR_OK;
+       }
+       LOG_TARGET_DEBUG(target, "Restarting from 0x%" TARGET_PRIxADDR, 
*address_p);
        /* This restores the pipeline and ensures one item gets reliably 
written */
        return write_memory_progbuf_startup(target, address_p, curr_buff, size);
 }
@@ -4970,7 +4975,8 @@ static int write_memory_progbuf_run_batch(struct target 
*target, struct riscv_ba
                /* TODO: If dmi busy is encountered, the address of the last
                 * successful write can be deduced by analysing the batch.
                 */
-               return write_memory_progbuf_handle_busy(target, address_p, 
size, buffer);
+               return write_memory_progbuf_handle_busy(target, address_p, 
end_address,
+                               size, buffer);
        }
        LOG_TARGET_ERROR(target, "Error when writing memory, abstractcs=0x%" 
PRIx32,
                        abstractcs);

-- 

Reply via email to